Troubleshooting
Common issues and solutions when working with the Forge CLI.
Authentication
Session Expired or Invalid
Symptom: Commands fail with "session expired" or "not authenticated" errors.
Solution: Re-authenticate:
forge login
The CLI automatically detects expired sessions and clears stale credentials. You do not need --force, as running forge login is sufficient.
"Mandatory fields are missing" or 400 Bad Request
Symptom: A command surfaces a generic 400 Bad Request: Mandatory fields are missing error rather than the usual "session expired" message.
Explanation: Your BFF session (stored in Redis) has timed out, but the expiry surfaced as a generic 400 instead of a 401. The CLI keeps your session alive automatically while you're actively running commands (proactive session touch every ~10 minutes plus auto-retry on 401/400). If you step away for 30+ minutes, the Redis session may expire.
Solution: Force a fresh login:
forge login --force # re-authenticate even if the CLI thinks you're logged in
"Stage is no longer available externally"
Symptom: Running any command after upgrading the CLI prints:
⚠ Stage is no longer available externally. Run `forge login` and select Sandbox or Production.
Explanation: Stage was repurposed as an internal-only environment in this CLI version. External users now choose between Sandbox and Production at login. Your stored session was cleared automatically.
Solution: Run forge login and pick Sandbox or Production. If you need access to a stage-tier API surface, choose Production → Stage apps at the tier prompt — that targets https://api.candescent.com/digitalbanking/stage.
"Production now distinguishes Stage-apps and Prod-apps"
Symptom: Any command after upgrading prints:
⚠ Production now distinguishes Stage-apps and Prod-apps.
Run `forge login` to re-authenticate and select your tier.
Explanation: The Production environment now requires a tier choice — Stage apps (DI API at …/digitalbanking/stage) or Prod apps (…/digitalbanking). Your previous Production session was stored without a tier, so the CLI cleared it to avoid silently picking the wrong DI API URL.
Solution: Re-authenticate and choose a tier:
forge login # interactive: env then tier
forge login -e production --tier stage # non-interactive
forge login -e production --tier prod
forge status afterwards will show the active tier and resolved DI API base URL.
GitHub CLI Token Expired
Symptom: forge widget submit or PR commands fail with "GitHub CLI token is expired or invalid."
Solution: Re-authenticate with the GitHub CLI:
gh auth login
gh auth status # verify
The CLI pre-checks GitHub authentication prior to submission. If the token has expired, it throws an explicit error with guidance.
Autocomplete
Tab completion for the CLI is shell-specific. If forge submission d<TAB> does not complete to deploy, follow the steps for your shell:
zsh (default on macOS)
# 1. Verify the source line exists in ~/.zshrc (added by `forge autocomplete zsh`)
grep FORGE_AC_ZSH ~/.zshrc
# Should output: FORGE_AC_ZSH_SETUP_PATH=.../autocomplete/zsh_setup && test -f $FORGE_AC_ZSH_SETUP_PATH && source $FORGE_AC_ZSH_SETUP_PATH;
# 2. Refresh the autocomplete cache
forge autocomplete --refresh-cache
# 3. Clear the zsh completions dump (the most common fix)
rm -f ~/.zcompdump*
# 4. Restart zsh
exec zsh
The .zcompdump* files are compiled caches that zsh creates from completion functions. After a CLI upgrade or rebuild they can become stale; deleting them forces compinit to regenerate them.
bash
# 1. Verify the source line exists in ~/.bashrc (or ~/.bash_profile on macOS)
grep FORGE_AC_BASH ~/.bashrc ~/.bash_profile 2>/dev/null
# If no output, add it:
echo 'FORGE_AC_BASH_COMPFUNC_PATH=~/Library/Caches/cdx-forge/autocomplete/functions/bash/forge.bash && test -f $FORGE_AC_BASH_COMPFUNC_PATH && source $FORGE_AC_BASH_COMPFUNC_PATH;' >> ~/.bashrc
# 2. Refresh the autocomplete cache
forge autocomplete --refresh-cache
# 3. Reload
source ~/.bashrc
Still Not Working?
-
On Linux, the cache directory is
~/.cache/cdx-forge/autocomplete(not~/Library/Caches/...). -
CLI developers: After source changes, run
pnpm run buildbeforeforge autocomplete --refresh-cache. The oclif manifest (which drives autocomplete) is regenerated during the build step. -
Full reset:
Bashrm -rf ~/Library/Caches/cdx-forge/autocomplete # macOS
# or: rm -rf ~/.cache/cdx-forge/autocomplete # Linux
forge autocomplete --refresh-cache
rm -f ~/.zcompdump* # zsh only
exec zsh
Widget Development
"Not Inside a cdx-extensibility-apps Project"
Symptom: forge widget create, forge widget preview, or forge widget build fails with this error.
Explanation: The CLI resolves the extensibility apps project in this order:
- Environment variable —
export FORGE_EXTENSIBILITY_APPS=/path/to/cdx-extensibility-apps - Current directory —
cdinto any directory inside a clone - Stored config — set automatically after the first auto-setup
- Auto-cache —
~/.forge/cdx-extensibility-apps(cloned automatically on first use)
Any widget or playground command auto-clones the public template to ~/.forge/cdx-extensibility-apps on first use if no checkout is found.
Widget Name Mismatch ("-widget" Suffix)
Symptom: You create a widget named spend-chart but the CLI shows it as spend-chart-widget in the preview picker.
Explanation: The Nx generator appends a -widget suffix to the project name. The CLI handles this automatically — you can use either spend-chart or spend-chart-widget in commands and the CLI resolves the correct project.
Mobile Preview: Web Bundling Failed
Symptom: forge widget preview <name> --platform mobile fails with Web Bundling failed...Unable to resolve "react-native-web".
Explanation: This happens when Expo attempts web bundling in the mobile sandbox. The CLI sets EXPO_NO_WEB=1 to suppress this, but if you see the error:
- Ensure you are running the latest version of the Forge CLI (
brew upgrade forge-cliorpnpm update -g @cdx-forge/cli) - Verify that
~/.forge/cdx-extensibility-apps/playground/mobile-sandbox/app.jsondoes not contain a"web"configuration section
Mobile Preview: QR Code Not Scanning
Symptom: Scanning the Expo QR code with the iPhone Camera app shows "no usable data found."
Solution: The iPhone Camera app does not handle exp:// URLs. Use the Expo Go app's built-in QR scanner instead:
- Install Expo Go from the App Store / Play Store
- Open Expo Go and tap the QR scanner
- Scan the QR code displayed in the terminal
Alternatively, press i in the terminal to open an iOS Simulator, or a for an Android emulator.
Mobile Preview: Expo Go "Opening Project..." Hangs
Symptom: Expo Go opens but stays stuck on "Opening project..." and never loads.
Cause: Your phone cannot reach Metro Bundler's local IP address. The phone and dev machine must be on the same Wi-Fi network, or you must use Expo's tunnel mode.
Solutions:
# Option 1: Connect your phone to the same Wi-Fi as your dev machine
# Option 2: Use tunnel mode (works across any network, including cellular)
cd ~/.forge/cdx-extensibility-apps/playground/mobile-sandbox
npx expo start --tunnel --port 8083
# Option 3: Use a simulator instead (no network needed)
# Press 'i' in the Metro terminal for iOS Simulator
# Press 'a' for Android emulator
Mobile Preview: Metro Bundler "Unable to Resolve Module"
Symptom: Metro fails with Unable to resolve module ... after adding a new widget or dependency.
Cause: Metro's cache is stale.
Solution: Clear caches and restart:
cd ~/.forge/cdx-extensibility-apps # or your project root
npx expo start --clear
If the error references your widget package name, run npm install at the project root to re-link the workspace package.
Web Preview: Browser Opens to Blank Page
Symptom: forge widget preview opens the browser but the widget slot is empty or the page does not load.
Solution: The CLI pre-checks that the OLB playground and the widget's remoteEntry.js are reachable before opening the browser. If you still see a blank page:
- Check that the OLB Docker playground is running:
docker ps | grep olb-playground - Check that the dev server is running: verify the Nx terminal output for build errors
- Reload the page — some Aspects register after the initial page load
Aspect Development
Banner or Aspect Not Appearing After Preview
Symptom: forge aspect preview opens the browser but the Aspect does not display.
Solutions:
- Reload the page — the OLB shell runs injected Aspects on load. Navigate to
http://localhost:4200and reload. - Check for syntax errors — if the generated JavaScript has a syntax error, the Aspect silently fails. Check the saved file under
./aspects/or check the browser console for errors. - Multiline message issue — see the next section.
Multiline Message Not Working
Symptom: The --message flag with \n shows a literal backslash-n instead of a newline.
Solution: Use ANSI-C quoting ($'...') so escape sequences are interpreted:
# Correct — $'...' interprets \n as a newline
forge aspect preview --template banner --message $'Headline\nSubline'
# Wrong — plain quotes pass literal \n
forge aspect preview --template banner --message 'Headline\nSubline'
Context-Aware Template Shows "Valued Customer"
Symptom: Templates like welcome-banner or personalized-toast show fallback text instead of the user's name.
Explanation: Context-aware templates use dbk.sessionInfo() which is only available in the OLB playground environment. If you are using --no-playground (local mock), the session context is unavailable and the template falls back to generic text.
Solution: Run without --no-playground to get live personalized data:
forge aspect preview --template welcome-banner --message 'Check out our new rates!'
Vendor presets or mock partner URLs fail
Symptom: forge aspect preview with --template vendor-script-loader (or another vendor-oriented template) and --preset <id> loads, but the browser console shows script errors or 404 for SDK URLs.
Solutions:
-
Run a mock partner server on the host and port your preset expects (defaults often use
http://localhost:4011). Presets ship with stub URLs only — they are not live vendor endpoints. -
Point the CLI at your mock server if it is not on the default port: set
MOCK_PARTNERS_URLorMOCK_PARTNERS_PORTso auto-discovery finds it before preview. -
Inspect generated code without opening a browser:
Bashforge aspect templates --id vendor-script-loader --preset glia --preview-code
OLB Docker Playground
"docker-compose.yml Not Found"
Symptom: The CLI cannot find the Docker Compose file.
Explanation: This file comes from cdx-extensibility-apps/playground/web/. The auto-setup should handle this; if it persists, set the environment variable:
export FORGE_EXTENSIBILITY_APPS=/path/to/cdx-extensibility-apps
Port 4200 Already in Use
Solution: Stop other containers or processes using that port, then retry:
docker ps # find the conflicting container
docker stop <container-id> # stop it
forge playground up
Docker Pull Unauthorized
Symptom: docker pull or forge playground up --pull fails with unauthorized from ghcr.io.
Explanation: During internal testing, the olb-playground image may be private on GitHub Container Registry. Authenticate Docker:
- Create a Personal Access Token (classic: scope
read:packages; or fine-grained with Packages: Read) - Log in:
echo YOUR_GITHUB_PAT | docker login ghcr.io -u YOUR_GITHUB_USERNAME --password-stdin
- Retry:
forge playground up --pull
When the image is published as public, anonymous pulls will work without this step.
Submission
Widget Submission: Repository Not Found
Symptom: forge widget submit fails with "Could not resolve to a Repository."
Explanation: This usually means the FI repository has not been created yet or the name does not match:
- Check repository status:
forge repo status - If no repository exists, create one:
forge repo init - Verify you have been added as a collaborator — check your email for a GitHub invitation
If the error persists after confirming repository access, the CLI displays the repository name it is trying to access so you can verify it with your administrator.
Localhost URLs in Submission
Symptom: The CLI warns about localhost URLs during forge widget submit.
Explanation: This is expected. If you developed with the mock API server or OIDC Toolkit, your widget contains localhost URLs that will not work in production. The CLI detects these and prompts you to provide production URLs before the PR is created.
To skip the prompt and inject a target-environment URL automatically, pass --source-url:
forge widget submit my-portfolio --source-url https://api.acmebank.com
Pre-Submit Lint Checks Failing
Symptom: forge widget submit aborts with ESLint, TypeScript, or markdownlint errors before creating the PR.
Explanation: By default, widget submit runs ESLint, TypeScript type-check, and markdownlint to keep PRs clean. Common fixes:
no-console— replaceconsole.logwith proper logging or remove debug statements.- TypeScript errors — run
npx tsc --noEmitlocally and fix surfaced types. - Markdown — make sure
README.mdhas no trailing spaces, uses consistent heading levels, and has a blank line before/after fenced code blocks.
To bypass the checks (for example, while debugging metadata issues):
forge widget submit my-portfolio --no-lint
Submission CI Failure: "tsup: not found" or "Cannot find module 'typescript'"
Symptom: A widget PR's CI fails with tsup: not found or Cannot find module 'typescript', especially for mobile widgets.
Explanation: Mobile widget builds use tsup, which lives in the widget's devDependencies. The CLI automatically adds tsup and typescript to the FI repo's root devDependencies and updates the lockfile during submission. If CI still fails:
-
The lockfile may not have been updated — re-submit the widget (the CLI now runs
npm installduring submission to sync the lockfile). -
If the CI uses a strict
npm ciand the lockfile is out of sync, push a manual lockfile update:Bashgh repo clone <org>/<repo> /tmp/fix -- --branch <branch>
cd /tmp/fix && npm install --package-lock-only
git add package-lock.json && git commit -m "fix: update lockfile" && git push
Submission CI Failure: "Cannot find module 'stage-nx-package.js'"
Symptom: A widget submission's CI fails referencing stage-nx-package.js.
Explanation: That script only exists in the cdx-extensibility-apps monorepo. The CLI strips its reference from the widget's project.json during submission. Older submissions made before this fix may still carry the reference.
Solution: Re-submit the widget with the latest CLI version, or manually remove the script reference from the widget's project.json and push a fix-up commit to the PR.
Updating an Existing Widget PR
If you need to push additional commits to an open submission PR (e.g., to address review feedback), use --update:
forge widget submit my-portfolio -u
# or: forge widget submit my-portfolio --update
To force a brand-new PR even if one is already open for the widget:
forge widget submit my-portfolio --new
OIDC Toolkit
Toolkit Not Starting
Symptom: forge oidc up fails or the container exits immediately.
Solutions:
- Ensure Docker is running:
docker ps - Check for port conflicts: the toolkit uses ports 3000 and 3001 by default. Override with
--backend-portand--frontend-port. - On Apple Silicon, the image runs via emulation. Allow extra time for the initial start.
Credentials Expired
The OIDC Toolkit auto-generates credentials with a 15-minute TTL. If your credentials expire:
forge oidc credentials # view current credentials
forge oidc status # full health check
The toolkit refreshes credentials automatically. If you need fresh credentials for a preview, re-run the preview command — it fetches new credentials from the running toolkit.
General
Graceful Exit
All interactive prompts include an explicit Exit option. You can also press Ctrl+C at any input prompt for a clean exit without error traces.