Skip to main content

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:

Bash
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:

Bash
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:

Bash
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:

Bash
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)

Bash
# 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

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 build before forge autocomplete --refresh-cache. The oclif manifest (which drives autocomplete) is regenerated during the build step.

  • Full reset:

    Bash
    rm -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:

  1. Environment variableexport FORGE_EXTENSIBILITY_APPS=/path/to/cdx-extensibility-apps
  2. Current directorycd into any directory inside a clone
  3. Stored config — set automatically after the first auto-setup
  4. 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:

  1. Ensure you are running the latest version of the Forge CLI (brew upgrade forge-cli or pnpm update -g @cdx-forge/cli)
  2. Verify that ~/.forge/cdx-extensibility-apps/playground/mobile-sandbox/app.json does 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:

  1. Install Expo Go from the App Store / Play Store
  2. Open Expo Go and tap the QR scanner
  3. 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:

Bash
# 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:

Bash
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:

  1. Check that the OLB Docker playground is running: docker ps | grep olb-playground
  2. Check that the dev server is running: verify the Nx terminal output for build errors
  3. Reload the page — some Aspects register after the initial page load

Aspect Development

Symptom: forge aspect preview opens the browser but the Aspect does not display.

Solutions:

  1. Reload the page — the OLB shell runs injected Aspects on load. Navigate to http://localhost:4200 and reload.
  2. 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.
  3. 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:

Bash
# 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:

Bash
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:

  1. 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.

  2. Point the CLI at your mock server if it is not on the default port: set MOCK_PARTNERS_URL or MOCK_PARTNERS_PORT so auto-discovery finds it before preview.

  3. Inspect generated code without opening a browser:

    Bash
    forge 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:

Bash
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:

Bash
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:

  1. Create a Personal Access Token (classic: scope read:packages; or fine-grained with Packages: Read)
  2. Log in:
Bash
echo YOUR_GITHUB_PAT | docker login ghcr.io -u YOUR_GITHUB_USERNAME --password-stdin
  1. 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:

  1. Check repository status: forge repo status
  2. If no repository exists, create one: forge repo init
  3. 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:

Bash
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 — replace console.log with proper logging or remove debug statements.
  • TypeScript errors — run npx tsc --noEmit locally and fix surfaced types.
  • Markdown — make sure README.md has 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):

Bash
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:

  1. The lockfile may not have been updated — re-submit the widget (the CLI now runs npm install during submission to sync the lockfile).

  2. If the CI uses a strict npm ci and the lockfile is out of sync, push a manual lockfile update:

    Bash
    gh 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:

Bash
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:

Bash
forge widget submit my-portfolio --new

OIDC Toolkit

Toolkit Not Starting

Symptom: forge oidc up fails or the container exits immediately.

Solutions:

  1. Ensure Docker is running: docker ps
  2. Check for port conflicts: the toolkit uses ports 3000 and 3001 by default. Override with --backend-port and --frontend-port.
  3. 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:

Bash
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.