Skip to main content

Troubleshooting

Common issues and solutions when working with the Forge CLI. Start with diagnostics, then jump to the section that matches the error.

If you seeGo to
forge doctor fails or looks stuckFirst step: run diagnostics
Session expired, 400 Bad Request, or login does not stickAuthentication and app selection
Checkout missing, invalid layout, or forge widget initExtensibility-apps checkout
nx not available, slow or hung npm install, blocked npmjsnpm, Nx, and Windows
C: disk full or IT limits storage on the system driveMove the checkout to another drive (Windows)
Preview never opens, blank playground, Docker errorsWeb preview and the OLB playground
Mobile preview, Metro, Expo Go, or QR codeMobile preview
Aspect not visible, \n, or vendor preset 404Aspect development
forge ask auth or session errorsAI docs search (forge ask)
Submit, lockfile, or CI failuresSubmission

First step: run diagnostics

Bash
forge doctor --verbose
forge doctor --network --verbose # after forge login and forge app select

forge doctor checks runtime (Node, CLI), auth, git/GitHub CLI, Docker, the extensibility-apps checkout, Nx, and mobile tooling. Mobile checks warn only. Without --strict, those warnings do not fail the run.

--network probes BFF reachability and API token exchange (login required; token exchange also needs forge app select). It does not test npm, GitHub, GHCR, or Expo. Those need the checks in the sections below.

Useful flags (see Command Reference for check ids):

FlagWhat it does
--verbose / -vInclude versions, resolved paths, and extra data fields. Use this when you file a support ticket.
--timeout <ms>Per-check timeout. Default is 8000 ms. On a slow Windows machine, the Nx probe can time out and doctor warns nx not available in extensibility-apps checkout even when a later npx nx --version works. Re-run with --timeout 60000 before you treat Nx as broken.
--check <id>Run only named checks (repeatable).
--skip <id>Skip named checks (repeatable).
--jsonMachine-readable report for scripts and CI.
--strictTreat warnings as failures (exit 1). Useful in CI.
--no-colorDisable ANSI colors (also honors NO_COLOR).

Exit codes: 0 when there are no failures (warnings and skips are allowed). 1 when any check fails, when --strict sees a warning, or when --check names an unknown id.

Focused checkout and Nx re-check:

Bash
forge doctor --verbose --timeout 60000 --check ext.root --check ext.rootValid --check nx.invocation
note

Refresh runs only when doctor resolved the managed cache at ~/.forge/cdx-extensibility-apps. If you are already inside another valid checkout, that path wins and the cache is not refreshed. When the cache is the resolved root and the refresh marker is older than about five minutes, the CLI runs git fetch --quiet origin. If local HEAD and origin/HEAD differ, it then runs git checkout -- ., git pull --ff-only, and npm install. That is why doctor sometimes sits on Installing dependencies (npm install).... Let it finish. Interrupting mid-install is a common cause of later Nx warnings.

A refresh can revert tracked files in the checkout. Generated widget folders under widgets/ are usually untracked and kept. Registry and workspace wiring in tracked files can disappear. If a widget you already created no longer previews after doctor, see Checkout refresh reverted my widget wiring.

Authentication and app selection

Session expired or invalid

Symptom: Commands fail with "session expired" or "not authenticated."

Solution: Force a fresh login:

Bash
forge login --force
forge status

If the CLI can still verify the session with the server, plain forge login prints that you are already logged in and tells you to pass --force. Use --force whenever a command fails with an auth error. The idle window is about 30 minutes. Doctor's auth.sessionExpiry check reports the same and recommends forge login --force.

Login succeeds, next command says you are not logged in

Symptom: forge login succeeds, then the next command reports "Not logged in." You may also see OS credential store unavailable — credentials will not persist between commands.

Cause: The OS keyring could not load, so credentials live only for that process.

Solution:

  • macOS: reinstall Forge for your CPU architecture (arm64 vs x64): brew reinstall forge-cli
  • Linux: install libsecret, for example sudo apt-get install libsecret-1-0

"Mandatory fields are missing" or 400 Bad Request

Symptom: A command fails with 400 Bad Request: Mandatory fields are missing instead of "session expired."

Explanation: A generic 400 can show up after you have been idle, or when a request is missing fields. The CLI retries once only when the body looks like a session expiry. If forge login --force does not clear it, the 400 is a different API error.

Solution:

Bash
forge login --force
forge status

GitHub CLI token expired

Symptom: forge widget submit fails with "GitHub CLI token is expired or invalid."

Solution:

Bash
gh auth login -h github.com
gh auth status

forge widget submit pre-checks GitHub authentication before it opens a PR. forge aspect submit does not run that pre-check.

App select and skipped network checks

Symptom: forge doctor --network shows SKIP for token exchange: no app with API keys selected (run forge app select). Or forge app select errors with a missing BFF app title or no keys.

Explanation: SKIP is not a pass. Token exchange needs a selected app with API keys. The BFF reachability check only needs login.

Solution:

Bash
forge app list
forge app select
forge status
forge doctor --network --verbose

If select says the app is missing a BFF app title, re-create the app in the Developer Console. If it says no keys were found, generate API keys in the Developer Console, then run forge app select again.

If an old session has no console environment set, run forge login (the CLI may already have cleared those credentials). If doctor still fails auth.environmentAvailable, use forge logout && forge login.

Console environment switch fails or apps look wrong after switch

Symptom: forge env switch errors with unknown console environment, or API/submission commands target the wrong apps after switching.

Solution:

Bash
forge status                    # confirm console environment (CLI label: Workspace)
forge env switch # interactive picker (Sandbox, Staging, or Production)
forge env switch sandbox # or production
forge app select # required after every successful switch

If available console environments are unknown, re-run forge login. For scripting, pass an explicit target: forge env switch sandbox --json.

AI docs search (forge ask)

Not logged in or auth errors

Symptom: forge ask fails immediately or mentions signing in again.

Solution:

Bash
forge status
forge login --force
forge ask 'How do I authenticate API requests?'

Stale or expired docs chat session

Symptom: forge ask fails with a message about an invalid or expired docs chat session.

Solution:

Bash
forge ask --new-session

Or pass a known session id with forge ask --session <id> when continuing a prior conversation.

Extensibility-apps checkout

Widget create, preview, build, and the OLB playground use a local clone of cdx-extensibility-apps. On first use the CLI clones it to the managed cache and runs npm install there. That first install can take several minutes.

Default location:

  • macOS / Linux: ~/.forge/cdx-extensibility-apps
  • Windows: %USERPROFILE%\.forge\cdx-extensibility-apps (Command Prompt) or $env:USERPROFILE\.forge\cdx-extensibility-apps (PowerShell)

Confirm the path doctor actually resolved:

Bash
forge doctor --verbose --check ext.root --check ext.rootValid

Look at ext.root. Do not assume a different folder.

A valid checkout has nx.json plus either playground/web/docker-compose.yml or a widgets/web / widgets/mobile folder. Fresh clones ship the playground compose file before the first forge widget create creates widgets/.

Checkout not found or invalid

Symptom: Doctor warns ext.root is not configured (not configured). If no root is resolved, ext.rootValid is skipped, not failed. Widget create (except --local), preview, and init auto-clone a missing cache. If the cache directory exists but is not a valid checkout, the CLI first tries git checkout -- . and git pull --ff-only inside it. If it is still invalid, they throw {path} exists but is not a valid cdx-extensibility-apps checkout.

Solution: Recreate the managed checkout. Do not delete it in place if it already contains widgets. Move it aside, then bootstrap:

Bash
# macOS / Linux
mv ~/.forge/cdx-extensibility-apps ~/.forge/cdx-extensibility-apps.bak
forge widget init
# Windows PowerShell
Move-Item "$env:USERPROFILE\.forge\cdx-extensibility-apps" "$env:USERPROFILE\.forge\cdx-extensibility-apps.bak"
forge widget init
REM Windows Command Prompt
move "%USERPROFILE%\.forge\cdx-extensibility-apps" "%USERPROFILE%\.forge\cdx-extensibility-apps.bak"
forge widget init

forge widget init is the bootstrap command for this cache. It does not appear in forge --help. forge widget preview and forge widget create (without --local) also clone the cache on first use if it is missing. forge widget create --local writes files only and does not clone.

Copy your widget folders back from the .bak tree (widgets/web and widgets/mobile) after init finishes. Then reinstall dependencies in the new checkout. See Reinstall dependencies.

Checkout refresh reverted my widget wiring

Symptom: Widget source is still under widgets/, but preview cannot find the widget, or mobile preview says the widget id is not in WIDGET_REGISTRY.ts.

Cause: A managed-cache refresh reset tracked files (registry, package.json workspace entries) while leaving untracked widget source.

Solution: Re-scaffold is not required if the source is intact. Prefer forge widget preview or forge widget build against the existing folder. If the registry row is gone, add it back from the mobile-sandbox README, or copy the registry file from your .bak checkout if you moved one aside.

Do not retry forge widget create on a name that already exists. The CLI throws Widget "…" already exists at …. It does not overlay or replace src/ on retry. After Nx generates a new widget, the CLI overlays template files only when the template is not sdk-demo.

Move the checkout to another drive (Windows)

Symptom: C: is low on space, or IT policy limits what you can store on the system drive. npm install in the extensibility-apps checkout fails or you cannot keep node_modules on C:.

Explanation: Forge expects the managed checkout at %USERPROFILE%\.forge\cdx-extensibility-apps. Copying the repo to D: without redirecting that path breaks widget commands. A Windows junction keeps the path Forge uses while storing files on another drive.

FORGE_EXTENSIBILITY_APPS alone does not redirect everything Forge touches under %USERPROFILE%\.forge. The junction makes the profile path transparently resolve to D:.

Solution: These steps were validated on Windows 11 Pro (64-bit) with administrator privileges. If a command fails, check permissions and compatibility with your IT team before you escalate.

Copy the full cdx-extensibility-apps tree (including node_modules if already installed), not an empty clone.

1. Copy the checkout to D:

$src = "$env:USERPROFILE\.forge\cdx-extensibility-apps"
$dst = "D:\.forge\cdx-extensibility-apps"
robocopy $src $dst /E /COPY:DAT /R:1 /W:1

Verify the copy before you continue:

Test-Path "D:\.forge\cdx-extensibility-apps\nx.json"
Test-Path "D:\.forge\cdx-extensibility-apps\playground\web\docker-compose.yml"

Both should return True. If you already created widgets, also confirm D:\.forge\cdx-extensibility-apps\widgets exists.

2. Release locks on the C: folder

cd $env:USERPROFILE
Get-CimInstance Win32_Process -Filter "Name = 'node.exe'" |
Where-Object { $_.CommandLine -match 'cdx-extensibility-apps' } |
ForEach-Object { Stop-Process -Id $_.ProcessId -Force }

Close any Explorer windows or terminals open under .forge.

Back up before creating the junction

Step 3 renames %USERPROFILE%\.forge\cdx-extensibility-apps. Confirm step 1's copy on D: is complete (including widgets/ if you already scaffolded) before you continue.

3. Create the junction and set the environment variable

$forge = "$env:USERPROFILE\.forge\cdx-extensibility-apps"
$docs = "D:\.forge\cdx-extensibility-apps"
Rename-Item $forge "$forge.bak"
New-Item -ItemType Junction -Path $forge -Target $docs
[Environment]::SetEnvironmentVariable("FORGE_EXTENSIBILITY_APPS", $docs, "User")
$env:FORGE_EXTENSIBILITY_APPS = $docs

4. Verify the junction

Get-Item $forge | Format-List FullName, LinkType, Target

Confirm LinkType is Junction and Target is D:\.forge\cdx-extensibility-apps.

5. Remove the backup folder

$bak = "$forge.bak"
$empty = "$env:TEMP\empty-del"
New-Item -ItemType Directory -Path $empty -Force | Out-Null
cmd /c "robocopy `"$empty`" `"$bak`" /MIR /R:0 /W:0 /NFL /NDL /NJH /NJS"
cmd /c rmdir /s /q "\\?\$bak"
Remove-Item $empty -Force

Open a new PowerShell window, then verify:

forge doctor --verbose --check ext.root --check ext.rootValid

Confirm ext.root resolves through the junction to D:\.forge\cdx-extensibility-apps, then retry your original forge command.

note

The junction redirects %USERPROFILE%\.forge\cdx-extensibility-apps to D:\.forge\cdx-extensibility-apps. Forge keeps using the profile path; checkout disk usage moves to D:. Other paths under %USERPROFILE%\.forge (for example the mock-server cache) stay on C: unless you relocate them separately.

npm, Nx, and Windows

Doctor warns nx not available in extensibility-apps checkout (fix cd <root> && npm install) when it cannot run Nx from the checkout. That is a warning, not a failure, unless you pass --strict. Widget commands still throw Nx is not available in this project. From the extensibility-apps directory run: npm install.

Nx is a local workspace tool. You do not need a global nx install. Doctor and widget commands try, in order: the checkout's local nx bin, then npx nx, then pnpm exec nx.

Before you declare Nx missing, raise the doctor timeout:

Bash
forge doctor --verbose --timeout 60000 --check nx.invocation

If the pass message says npx nx or pnpm exec nx instead of nx, the local node_modules/nx bin is missing or broken. Reinstall dependencies.

Reinstall dependencies

Work in the managed checkout root. Keep package-lock.json. Do not delete it.

Bash
# macOS / Linux
cd ~/.forge/cdx-extensibility-apps
node -v
npm -v
npm config get registry
npm ping
npm install --timing --loglevel=verbose
npx nx --version
# Windows PowerShell
cd $env:USERPROFILE\.forge\cdx-extensibility-apps
node -v
npm -v
npm config get registry
npm ping
npm install --timing --loglevel=verbose
npx nx --version
REM Windows Command Prompt
cd /d "%USERPROFILE%\.forge\cdx-extensibility-apps"
node -v
npm -v
npm config get registry
npm ping
npm install --timing --loglevel=verbose
npx nx --version

The CLI requires Node.js 18+. The extensibility-apps checkout README asks for npm 9+ (some Node 18 builds ship an older npm). Run npm install from the checkout root, not from a widget subdirectory.

--timing --loglevel=verbose prints progress. The idealTree and cache-scan phases can look idle. That is normal for several minutes on a first Windows install. If verbose output has not printed a new line for a long stretch (for example 10+ minutes with no HTTP activity), treat it as stuck. Capture the log instead of waiting indefinitely.

Do not interrupt a healthy install. Stopping mid-extract is a common cause of "package present, dependency missing" trees and repeated Nx errors.

When npx nx --version prints a version, re-run:

Bash
forge doctor --verbose --timeout 60000 --check nx.invocation --check ext.rootValid

Then retry the original widget command (forge widget preview or forge widget create), not a second create of the same name.

npm errors

Match the log, then fix that class:

ErrorLikely causeWhat to do
ENOTFOUND, EAI_AGAINDNS or blocked hostConfirm npm config get registry is https://registry.npmjs.org/. Ask IT to allowlist registry.npmjs.org.
ETIMEDOUT, ECONNRESET, socket hang upFirewall, proxy, or VPNConnect to the corporate VPN if required. Ask IT to allow HTTPS to the registry.
E401, E403, 401 / 403Registry authYou are hitting a registry that requires credentials, or a proxy is intercepting npm. See Corporate network and registry access.
UNABLE_TO_GET_ISSUER_CERT, CERT_HAS_EXPIRED, self signed certificateTLS inspectionTrust the corporate CA with NODE_EXTRA_CA_CERTS pointing at a PEM bundle from IT. Do not set strict-ssl=false.
ENAMETOOLONGWindows path lengthEnable Win32 long paths (LongPathsEnabled) and git config --system core.longpaths true. Keep the checkout under the default .forge path.
EPERM, file locked, EBUSYAntivirus or indexerSee Windows VDI and endpoint scanning.

When npm fails, it prints a path under the npm cache _logs directory. Attach that file when you escalate.

Clean node_modules (only after you have logs)

If npx nx --version still fails after a completed npm install, and you already saved the verbose log:

Bash
# macOS / Linux
cd ~/.forge/cdx-extensibility-apps
rm -rf node_modules
npm install --timing --loglevel=verbose
npx nx --version
# Windows PowerShell
cd $env:USERPROFILE\.forge\cdx-extensibility-apps
Remove-Item -Recurse -Force node_modules
npm install --timing --loglevel=verbose
npx nx --version
REM Windows Command Prompt
cd /d "%USERPROFILE%\.forge\cdx-extensibility-apps"
if exist node_modules rmdir /s /q node_modules
npm install --timing --loglevel=verbose
npx nx --version

Leave package-lock.json in place. A full reinstall re-resolves the workspace (web React 18 and mobile React 19 in one tree). Use it as an escalation step, not the first fix.

Windows VDI and endpoint scanning

On managed Windows, real-time scanning of tens of thousands of small files under node_modules makes npm install look hung.

Ask IT for path exclusions (do not turn scanning off yourself):

  • The checkout: %USERPROFILE%\.forge\cdx-extensibility-apps
  • node_modules inside that checkout
  • The npm cache: %LOCALAPPDATA%\npm-cache

If IT cannot exclude Defender or a third-party agent (CrowdStrike, Carbon Black, Symantec, and similar), expect first installs to take much longer. Keep verbose logs running so you can tell a slow scan from a blocked registry.

When C: is too small for the checkout and node_modules, see Move the checkout to another drive (Windows).

Windows also needs long-path support for the React Native tree. If install fails with ENAMETOOLONG, have IT enable long paths before you wipe node_modules again.

Corporate network and registry access

Local widget create and preview need outbound HTTPS to:

  • registry.npmjs.org (npm install of the checkout)
  • GitHub (github.com) for the template clone
  • ghcr.io for OLB playground images only (web preview / forge playground up --pull). Widget create and mobile preview do not pull GHCR.

forge doctor --network does not prove any of those. Use npm ping, git ls-remote https://github.com/candescent-dev/cdx-extensibility-apps.git, and the Docker pull error text.

Default. Point npm at public npm:

Bash
npm config get registry
npm ping

You want https://registry.npmjs.org/ and a successful PING/PONG. If the host is blocked, ask IT to allowlist registry.npmjs.org. There is no Candescent-hosted npm registry for customers.

Your own registry. If your institution already runs an npm-compatible registry that mirrors public packages, you can use it for the local checkout install:

Bash
cd ~/.forge/cdx-extensibility-apps
npm install --registry=https://npm.example.bank.internal --timing --loglevel=verbose

Prefer a one-off --registry flag (or a checkout-local .npmrc) over npm config set registry, which writes your user-level ~/.npmrc.

warning

forge widget submit does not copy the apps-checkout package-lock.json or .npmrc. Web submit copies the widget project (minus node_modules, .nx, and dist). Mobile submit generates the project in the FI repo, overlays src/, and merges missing devDependencies, peerDependencies, and the build/dev scripts. It does not merge ordinary dependencies.

Submit does run npm install in a temp clone of the FI promotions repo on your machine. That install honors user/global npm config (~/.npmrc), not the checkout .npmrc. If you permanently change the user-level registry, the FI package-lock.json can record private resolved URLs. GitHub CI cannot fetch those.

Do not change the user-level default registry if you will submit. Restore https://registry.npmjs.org/ (or unset the override) before forge widget submit.

If neither public npm nor your institution's registry can serve the checkout, local widget create/preview cannot finish. Collect the support bundle and escalate.

Widget development

Widget name mismatch (-widget suffix)

Symptom: You create spend-chart but the preview picker shows spend-chart-widget.

Explanation: Web Nx generators often append -widget. The CLI accepts either form. Many mobile widgets have no suffix.

Web preview and the OLB playground

First compile looks stuck, or the browser never opens

Symptom: forge widget preview sits on the Nx compile, or prints Dev server not ready — remoteEntry.js was not detected in time / Mount API did not become ready in time and does not open a browser.

Explanation: The first compile often takes 2–5+ minutes. The CLI waits up to --ready-timeout seconds (default 300) for remoteEntry.js, then up to 20 seconds for the playground mount API on port 3001. If either is late, it prints a manual URL and skips opening the browser.

Solution: Wait until the Nx terminal shows a successful compile. Open the URL the CLI printed. That is http://localhost:4200 when the mount API succeeded, or the playground manager deep link (http://localhost:4200/playground?...) when it did not. Increase the wait with --ready-timeout if the machine is slow. Check Docker with:

Bash
cd ~/.forge/cdx-extensibility-apps/playground/web
docker compose ps

If Docker is down, start Docker Desktop and retry, or preview the Nx server only:

Bash
forge widget preview my-portfolio --no-playground

Blank page after the browser opens

Symptom: The playground loads but the widget slot is empty.

Solution:

  1. Confirm docker compose ps in playground/web shows the stack healthy (shell on 4200, BFF on 3001 when preview needs the mount API).
  2. Check the Nx terminal for compile errors.
  3. Reload http://localhost:4200. Some Aspects register after the first load.

Playground port already in use

Symptom: forge playground up fails because a published compose port is taken (often 4200 or 3001; the stack also publishes other host ports).

Explanation: With the playground on, forge widget preview always moves the Nx dev server off 4200 onto 4300, then scans upward for a free port. The playground shell still binds host 4200. forge playground up does not remap those compose ports. Stop the conflicting process or container, then retry:

Bash
docker ps
docker stop <container-id>
forge playground up

Docker daemon not running

Symptom: Preview or forge playground up prints that Docker is not running or docker.sock is unreachable.

Solution: Open Docker Desktop and wait until docker info succeeds. To skip the playground: forge widget preview --no-playground or forge aspect preview --no-playground.

docker-compose.yml not found

Symptom: The CLI cannot find playground/web/docker-compose.yml.

Explanation: That file ships in the extensibility-apps checkout. Pull or recreate the managed checkout (Checkout not found or invalid), then retry. Doctor's docker.composeFile check reports the same.

Docker pull unauthorized (ghcr.io)

Symptom: docker pull or forge playground up --pull fails with unauthorized from ghcr.io.

Solution: Authenticate Docker with a GitHub PAT (classic read:packages, or fine-grained Packages: Read):

Bash
echo YOUR_GITHUB_PAT | docker login ghcr.io -u YOUR_GITHUB_USERNAME --password-stdin
forge playground up --pull

If the container is unhealthy, the CLI runs docker compose down, pull --ignore-buildable, and up -d --force-recreate, then waits again. From the checkout root doctor reported as ext.root:

Bash
cd playground/web
docker compose down && docker compose pull --ignore-buildable && docker compose up -d --force-recreate

Mobile preview

Mobile preview targets an iOS Simulator or Android Emulator by default (--mobile-device ios|android). The CLI prompts when both exist and aborts when neither does. Physical-device Expo Go is a fallback after emulator boot fails, not the primary path.

Dependencies not installed, or checkout too old

Symptom: Preview prints Dependencies not installed or This cdx-extensibility-apps checkout is too old for Forge mobile preview.

Solution: From the checkout root, run npm install (Reinstall dependencies). For an old checkout, update or recreate the managed cache (Checkout not found or invalid).

Widget not in the mobile registry

Symptom: Widget id "<name>" is not in playground/mobile-sandbox/registry/WIDGET_REGISTRY.ts.

Solution: The widget source may exist while the registry row was reverted. See Checkout refresh reverted my widget wiring.

QR code or Expo Go hang (physical device fallback)

Symptom: The iPhone Camera app shows "no usable data found," or Expo Go stays on "Opening project..."

Solution: The Camera app does not handle exp:// URLs. Use Expo Go's built-in scanner. Phone and machine must be on the same Wi-Fi. Prefer the simulator/emulator (--mobile-device ios or android) so you do not need that network path.

Do not start Expo by hand from playground/mobile-sandbox. That skips the widget preview target the CLI sets. Re-run forge widget preview <name> --platform mobile.

Forge opens the simulator or emulator itself (simctl on iOS). Press i in Metro only if auto-launch failed. If macOS blocked Automation (osascript -1743), pressing i can crash Metro. Do not press a in Metro on Android unless you need to reinstall Expo Go.

On Windows, if the Android emulator times out, enable Hyper-V or Windows Hypervisor Platform.

Metro Unable to resolve module

Symptom: Metro cannot resolve a module after you add a widget or dependency.

Explanation: By default, preview deletes Metro cache directories, then starts Expo with --clear. --no-clear-metro-cache skips only the directory delete. Expo still starts with --clear.

Solution: Re-run preview without --no-clear-metro-cache. If the missing module is a workspace package, run npm install at the checkout root.

Aspect development

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

Solutions:

  1. Reload http://localhost:4200. The OLB shell runs injected Aspects on load.
  2. Check ./aspects/ and the browser console for syntax errors. A broken script fails silently.
  3. Multiline --message issue: see the next section.

Multiline message not working

Symptom: --message with \n shows a literal backslash-n.

Solution: Use ANSI-C quoting ($'...') in bash/zsh:

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: welcome-banner shows Valued Customer, or personalized-toast shows Hi there!, instead of the user's name.

Explanation: Those templates call dbk.sessionInfo(), which exists in the OLB playground. --no-playground (local mock) has no session, so they fall back (Valued Customer vs there).

Solution: Run without --no-playground:

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 template) and --preset <id> loads, but the console shows script errors or 404 for SDK URLs.

Solutions:

  1. Preview tries to clone cdx-mock and start partner mocks when generated code or preset options reference :4011. If that fails, run a mock partner server on the host and port the preset expects (often http://localhost:4011). Preset URLs are stubs, not live vendor endpoints.

  2. Set MOCK_PARTNERS_URL or MOCK_PARTNERS_PORT if your mock is not on the default port.

  3. Inspect generated code without a browser:

    Bash
    forge aspect templates --id vendor-script-loader --preset engagement-script-loader --preview-code

Submission

Widget submission: repository not found

Symptom: forge widget submit prints Failed to access repository "…", Failed to clone: …, remote: Repository not found., or Could not determine repository name. Run forge repo status.

Explanation: The FI repository is missing, the name does not match, or GitHub auth cannot see it.

  1. Check repository status: forge repo status
  2. If no repository exists, create one: forge repo init
  3. Confirm you accepted the GitHub collaborator invitation

The CLI prints the repository name it tried so you can verify it with your administrator.

Localhost URLs in submission

Symptom: The CLI warns about localhost URLs during forge widget submit.

Explanation: Expected if you developed against the mock API. Those URLs will not work in production. The CLI prompts for production URLs before it opens the PR.

Skip the prompt with --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 or TypeScript errors before creating the PR. Markdownlint may show a non-blocking warning (markdown issues (non-blocking)).

Explanation: By default, submit runs Nx ESLint (nx lint), npm run typecheck in the widget directory, and markdownlint on README.md. Markdownlint warnings do not abort the submit. TypeScript failures do. ESLint rule failures abort; a missing ESLint plugin or missing @nx/eslint is a skip or warning. Common fixes:

  • no-console — remove debug console.log or replace it with proper logging.
  • TypeScript — run npm run typecheck in the widget directory and fix the types.
  • Markdown — no trailing spaces, consistent heading levels, blank line before and after fenced code blocks.

To bypass the checks while debugging metadata:

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 widgets often declare tsup in devDependencies. Submit copies those tools into the FI repo root package.json on the web copy path and the mobile fallback copy path. The usual mobile path generates the widget with Nx in the FI clone, overlays src/, and merges missing devDependencies, peerDependencies, and build/dev scripts. It does not run that root-devDependency helper. If CI still fails:

  1. Re-submit the widget so submit can sync the lockfile.

  2. If CI uses strict npm ci and the lockfile is still stale:

    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

If you pointed user-level npm at a private registry, that lockfile refresh can record private resolved URLs. Restore public npm before submit. See Corporate network and registry access.

Updating an existing widget PR

Push more commits to an open submission PR:

Bash
forge widget submit my-portfolio -u
# or: forge widget submit my-portfolio --update

Force a new PR even if one is already open:

Bash
forge widget submit my-portfolio --new

If you still need help

Send the platform team the following (redact tokens, cookies, and any _authToken / password lines from .npmrc or npm logs):

  1. The command that failed and the full terminal error
  2. OS and shell (for example Windows 11 23H2 + PowerShell; run winver on Windows)
  3. forge --version, node -v, npm -v
  4. forge doctor --verbose --json saved to a file (forge doctor --verbose --json > doctor.json)
  5. For install issues: the npm timing/debug log from npm install --timing --loglevel=verbose, plus npm config get registry and npm ping output
  6. The checkout path from ext.root and git status inside that checkout

The JSON doctor report includes platform and Node version. Treat it as internal: it can contain username, org, institution, app ids, and absolute paths, but not session tokens.