Skip to content

Troubleshooting

If a command failed, find your error here. Each entry covers what you see, why it happens, and how to fix it.

Authentication

Token rejected after login (401)

What you see: A command exits with a 401. The wording varies by command family: apps commands print Auth failed (401): <reason>. Run \orion login` to refresh credentials.(the reason is whatever the server returned, ortoken rejectedif the body is empty);versionscommands printAuthentication expired or invalid.followed byRun `orion login` to refresh your credentials.` on the next line.

Why: Your stored access token is no longer accepted by the server. The most common reasons are: the token expired, you (or an admin) revoked it, or your account permissions changed.

Fix: Run orion logout && orion login to authenticate fresh. If that doesn't help, run orion auth status to confirm whether the local token is still within its TTL, and contact your tenant admin if it looks like the account was revoked.

Missing scope (403)

What you see: A 403 with a message of the form Forbidden (403): <reason>. — typically missing required scope when the body is empty, or whatever the server returned otherwise.

Why: Your account is authenticated, but the OAuth client behind your clientId wasn't granted the scope the endpoint requires. The server issues a token without scopes it isn't allowed to grant, and developer-API endpoints reject it.

Fix: Contact your tenant administrator and ask them to grant the missing scope to your OAuth client in the developer portal. After that, run orion logout && orion login to pick up a token with the new scope.

Browser doesn't open during orion login

What you see: orion login prints a URL and a loading indicator, but no browser window opens.

Why: The CLI couldn't launch your default browser automatically. The local callback server is still listening on http://localhost:9876, so the flow isn't broken — it just needs you to reach the URL by hand.

Fix: Copy the URL the CLI printed into your browser, complete the OAuth flow, and the CLI picks up the callback automatically.

Login hangs after browser approval

What you see: You approve the OAuth prompt in the browser, but the CLI never finishes — it sits on the loading indicator forever.

Why: Port 9876 (the CLI's local callback listener) is bound by another process, so the OAuth callback can't reach the CLI.

Fix: Run lsof -i :9876 (macOS / Linux) or netstat -ano | findstr :9876 (Windows) to find the conflicting process. Stop it and retry orion login.

Apps and versions

App not found by slug

What you see: orion apps info <slug> exits with No app found for slug "<slug>".

Why: The slug doesn't match any app you own on this tenant, or you're authenticated as a different developer than the one who owns it.

Fix: Run orion apps list to see the apps you actually own, and orion auth whoami to confirm which identity you're logged in as.

A version came back rejected

What you see: A version you submitted appears with status rejected in orion versions list.

Why: The marketplace reviewer rejected the submission. The review thread on the version explains what they want changed.

Fix: Run orion versions show <version> to read the review thread, address the feedback, bump the version in orion-app.json, and re-run orion publish.

Server returned 500

What you see: A read command (orion apps list, orion versions list, etc.) exits with Request failed (500): <server message> (from the apps family) or Request failed (500). (from the versions family).

Why: Something failed inside the server while handling your request.

Fix: Retry — these are usually temporary. If it reproduces, open an issue with the exact command, the timestamp (UTC), and your tenant subdomain so Orion support can correlate it against server logs.

Publishing

Publish was cancelled at the prompt

What you see: orion publish prints Publish cancelled and exits cleanly.

Why: You answered n (or anything other than y) at the confirmation prompt.

Fix: Re-run orion publish and answer y when it asks you to confirm.

dist/index.js missing from orion publish or orion validate

What you see: A row prints dist/index.js missing — run \orion build`andorion publishexits withRun `orion validate` to see all errors before publishing`.

Why: dist/index.js doesn't exist (or dist/ is empty), so there's nothing to upload.

Fix: Run orion build to produce a bundle, then re-run orion publish.

Validation failures from orion publish

What you see: orion publish prints one or more rows from the validation step (manifest schema problems, scope shape errors, bundle issues), then exits with Run \orion validate` to see all errors before publishing`.

Why: One or more checks that publish runs against orion-app.json, the bundle, or the source archive failed.

Fix: Run orion validate for the full list of failing checks and the offending fields. Reconcile orion-app.json and your build, then re-run orion publish. New SMART scopes go through marketplace review before they're usable in production.

Version already published

What you see: orion publish exits with an error that the version already exists.

Why: The marketplace doesn't allow re-uploading the same version value. Each publish needs a new semver.

Fix: Bump version in orion-app.json (e.g. 1.0.51.0.6) and re-run orion publish.

Dev server

Tunnel doesn't open

What you see: orion dev starts but no public tunnel URL is printed, or the tunnel step fails.

Why: cloudflared ships as an npm dependency of @orion-ehr/cli and the binary is resolved at runtime via the cloudflared package's bin export. If npm install hasn't run (or the install was incomplete), the binary isn't on disk for the CLI to spawn.

Fix: Reinstall the CLI (npm install -g @orion-ehr/cli@latest) so the bundled cloudflared binary lands in node_modules/cloudflared/bin/. If your sandbox can already reach localhost (rare), pass --no-tunnel to skip the tunnel entirely.

iframe is blank in the host EMR

What you see: Vite is running, the tunnel is up, but loading your app in the host EMR shows an empty iframe or a loading spinner that never completes.

Why: Either the sandbox tenant didn't pick up the new tunnel registration (most often: the tunnel URL changed since the last orion dev and the sandbox is still pointed at the old one), or your bundle is failing to mount inside the iframe.

Fix: Stop and restart orion dev so the sandbox re-registers the tunnel. If the iframe is still blank, open your browser's devtools, switch to the iframe context, and check the console for errors from your bundle.

CLI itself

No host configured

What you see: Any command exits with No host configured. Run \orion config host` to point the CLI at your home tenant.`

Why: The host field in orion.config.ts is empty.

Fix: Run orion config host to set it interactively. If orion config show confirms the host is set but you still see this error, restore the literal-quoted form in orion.config.ts (e.g. host: 'https://your-tenant.staging.orionsoftware.io') — manual edits that break the quoting can confuse the parser.

orion --version shows the old number after upgrade

What you see: You ran orion upgrade but orion --version still prints the old version.

Why: npm's global install cache is serving the old binary. On Windows with nvm-windows, the global shim sometimes doesn't repoint to the new install.

Fix: Run npm cache clean --force && npm install -g @orion-ehr/cli@latest. Then run which orion (macOS / Linux) or where orion (Windows) to confirm the path resolves to the freshly installed binary.

Still stuck?

Open an issue at github.com/orion-software-corp/orion-ehr-cli/issues. Include the exact command you ran, the full output, and the version printed by orion --version so we can reproduce it.

Documents @orion-ehr/cli v0.0.15 — released under the MIT License.