Troubleshooting¶
Use this catalog when setup, onboarding, deploy, routing, access, or publishing does not behave as expected. Each entry names where the symptom appears, the most likely cause, the customer action, and the evidence to collect.
For the escalation path and packet, see Support and escalation. For deploy field meanings, status values, and evidence packets, see Deploy status and evidence.
Start Here¶
Pick the row that matches the symptom and run the first command before opening a support packet.
| Symptom | First command | What it tells you |
|---|---|---|
| Local setup or GitHub connection looks incomplete | aegis doctor --json |
Whether the local session and GitHub connector are ready. |
| A repo may not be granted to the GitHub App | aegis github status --project-repo <owner/repo> --require --json |
Whether the selected repo is available to the GitHub App installation. |
| Forge cannot fetch source or no webhook deploy starts | map doctor --app <owner/repo> |
Whether Forge knows the app and repo registration needed for deploys. |
| You pushed code but do not know whether Forge saw it | map versions <app> |
The internal versions, aliases, published record, and canary split known for the app. |
| You have a deployment ref and need the current phase | map --json status <deployment-ref> |
The deploy phase and stage fields: review, build, runtime, and route. |
| A deploy failed or was blocked | map --json evidence <deployment-ref> |
The review, build, runtime, route, or smoke evidence recorded for that deployment. |
A map command reports an API status, such as map: MAP returned <status> or map: onboard returned <status> |
map whoami |
The saved control-plane endpoint and local login metadata the CLI used for the request. |
| Protected-app access looks wrong | map access plan --repo-dir . |
The access policy the CLI resolves from access.yaml and flags. |
| The planned access policy is correct but not applied | map access apply --repo-dir . |
The policy write result. It does not edit mithran.yaml, build, publish, or retire a route. |
If a command returns a deployment ref, keep using that same ref for status and
evidence checks. If you do not have a deployment ref, start with
map versions <app>.
Debug without guessing¶
Use the smallest source that proves the current state:
| Question | Use |
|---|---|
| Is local setup ready? | aegis doctor --json |
| Is the repo granted to the Forge GitHub App? | aegis github status --project-repo <owner/repo> --require --json |
| Is the repo registered with Forge? | map onboard output, then map doctor --app <owner/repo> as a diagnostic. |
| Did a deploy start? | map versions <app> and the deployment ref it shows under internal versions or aliases. |
| Which deploy stage failed? | map --json status <deployment-ref> |
| What evidence did Forge record? | map --json evidence <deployment-ref> |
| Which version does the clean public URL serve? | map versions <app> and the published pointer. |
| Is protected sharing resolved correctly? | map access plan --repo-dir ., map access apply --repo-dir ., and allowed/denied browser or API checks. |
Do not treat an API error as a build, runtime, or route failure until deploy status says that stage failed. Do not retry a command that can change deploy, publish, canary, rollback, onboarding, or access state after a response-read or parse error until you inspect current state with the read commands above.
Setup and GitHub App¶
aegis setup or aegis doctor says setup is incomplete¶
Where you see it: local terminal after aegis setup or
aegis doctor --json.
Probable cause: the local session, GitHub App installation, or repo grant is missing.
Customer action: run aegis setup again for local account or profile
issues and follow any browser flow it opens. Then run
aegis github status --project-repo <owner/repo> --require --json for the repo
you plan to deploy.
If the GitHub App or repo grant is missing, use the CLI-provided setup link
when one is shown, or ask the GitHub org admin to grant the repo in GitHub App
settings.
Next command or log: aegis doctor --json, then
aegis github status --project-repo <owner/repo> --require --json.
Evidence to collect: aegis doctor --json output, repo-scoped
aegis github status output, GitHub account or org, repo owner/name, and any
setup URL error shown in the browser.
GitHub App install lands on a "denied" page¶
Where you see it: browser after installing the Forge GitHub App.
The setup flow shows a denied GitHub connector page.
Probable cause: the App was installed directly from its GitHub page instead of through the customer setup link. The App may be installed in GitHub, but Forge did not record the connection to your account.
Customer action: run aegis setup and use the install link it gives you.
Details: Connect GitHub.
Next command or log: aegis doctor --json from the target checkout.
Evidence to collect: browser URL, GitHub App installation owner, and
aegis doctor --json output from the target checkout.
Onboarding and source access¶
Source fetch fails¶
Where you see it: Forge deploy status, custom-CI GitHub Actions log, or control-plane response during source snapshot/fetch.
Probable cause: the repo is not granted to the Forge GitHub App shown by the customer setup link, the repo has not been onboarded, or the deploy request uses the wrong installation ref.
Customer action: confirm the repo grant in GitHub App settings, run
map doctor --app <owner/repo>, and confirm the deploy request uses the
installation ref from onboarding.
Next command or log: Forge deploy status, map --json status <id> when
you have a control-plane ID, or custom-CI GitHub Actions log, then
aegis doctor --json.
Evidence to collect: failed deploy status, control-plane response, GitHub App grant state, repo owner/name, commit SHA, and GitHub Actions run URL when custom CI is involved.
map onboard returns an API error¶
Where you see it: local terminal after
map onboard --installation-ref <installation-ref> <owner/repo> --repo-dir ..
Probable cause: the repo slug, installation ref, setup context, GitHub App grant, or project/app ref does not match the account context used by Forge.
Customer action: confirm the repo is granted to the Forge GitHub App shown
by the customer setup link. Re-run map onboard only after correcting the repo
slug, installation ref, setup context, GitHub App grant, or project/app ref.
Next command or log: map onboard --installation-ref <installation-ref>
<owner/repo> --repo-dir ., then map doctor --app <owner/repo>.
Evidence to collect: onboard command, HTTP status and response body, repo
owner/name, GitHub App grant state, and map doctor --app output.
Deploy trigger and custom-CI configuration¶
Webhook deploy does not start¶
Where you see it: no Forge deploy appears after pushing the main branch,
a release/* branch, or a release/* tag.
Probable cause: the repo is not granted to the Forge GitHub App, the repo is not onboarded, or the pushed ref is not a deploy trigger.
Customer action: confirm the GitHub App grant, run
map doctor --app <owner/repo>, and confirm the pushed ref is main, a
release/* branch, or a release/* tag. Forge evaluates those as
refs/heads/main, refs/heads/release/*, and refs/tags/release/*. If the
repo is not registered, run
map onboard --installation-ref <installation-ref> <owner/repo> --repo-dir ..
Next command or log: map doctor --app <owner/repo>, GitHub App settings,
and the pushed ref.
Evidence to collect: repo owner/name, pushed ref, GitHub App grant state,
map doctor --app output, and tenant/account/project/app refs.
Custom-CI deploy auth fails¶
Where you see it: GitHub Actions map-deploy log during the custom-CI
workflow run or deploy request setup.
Probable cause: the custom-CI workflow needs repo registration from
map onboard and a committed map-deploy.yml generated with
--with-ci-workflow. It also needs GitHub Actions id-token: write permission
and the required non-secret MAP_* repo Variables used by the workflow. They
may be missing if the repo was copied, onboarding was not run, the workflow was
deleted, or repo Variables were not set.
Customer action: run map onboard --installation-ref <installation-ref>
<owner/repo> --repo-dir . --with-ci-workflow and review the generated workflow
if the repo uses custom CI. Confirm required GitHub repo Variables:
MAP_INSTALLATION_REF, MAP_APP_REF, MAP_CONTROL_ENDPOINT, and
MAP_AUTH_ENDPOINT. Set MAP_CONTROL_ENDPOINT and MAP_AUTH_ENDPOINT from
the account setup values.
Add MAP_TENANT_REF, MAP_ACCOUNT_REF, and MAP_OIDC_AUDIENCE only when your
account uses those refs or audience settings.
Next command or log: GitHub Actions map-deploy run log, then
map doctor --app <owner/repo>.
Evidence to collect: Actions run URL, workflow or deploy-request error, the
workflow file revision, relevant MAP_* repo Variable names and values that
are not secrets, and map doctor --app output.
Nothing deploys when I push¶
Where you see it: no new deployment ref appears in map versions <app>
after a push, and no GitHub Deployment status appears for the pushed commit
when that projection is available.
Probable cause: by default, only refs/heads/main,
refs/heads/release/*, and refs/tags/release/* trigger built-in webhook
deploys. Feature branches and tags such as v1.2.3 are intentionally ignored
by the built-in webhook path. If the repo uses the optional custom-CI workflow,
check that workflow's triggers instead; the generated workflow uses
release/** branches, tags matching v[0-9]+.[0-9]+.[0-9]+, and manual
dispatch.
Customer action: push main for preview, push a release/* branch or
release/* tag for production, run the optional custom-CI workflow, or request
the deploy directly. If an operator needs to request a deploy directly, run
map deploy --repo <owner/repo> --env production --ref <git-ref> --installation-ref <installation-ref>.
See Deploy.
Next command or log: map versions <app>, pushed ref, GitHub App grant
state, and GitHub Actions tab only when custom CI is involved. When a
deployment ref appears, use map --json status <deployment-ref> and
map --json evidence <deployment-ref>.
Evidence to collect: pushed ref, repo owner/name, GitHub App grant state,
map versions <app> output, GitHub Deployment status when present, and
custom-CI workflow/run details when custom CI is involved.
map deploy is rejected before a deploy starts¶
Where you see it: local terminal after running map deploy or
map deploy-request.
Probable cause: the command did not include a Git ref or SHA, the SHA is not a 40-character Git SHA, the repo slug is wrong, the saved map-control endpoint or token is missing, or the control plane rejected the deploy request.
Customer action: pass exactly one deploy target by ref or SHA, confirm the
repo is in owner/repo form, include the GitHub App installation ref for real
source fetches, and run map login save if the CLI has no saved map-control
endpoint or token.
Next command or log: map deploy --repo <owner/repo> --env <app-env>
--ref <git-ref> --installation-ref <installation-ref>, or the same command
with --sha <40-hex-sha> instead of --ref.
Evidence to collect: exact command, CLI error, repo owner/name, ref or SHA, installation ref, and target app environment.
A map command reports an API status¶
Where you see it: local terminal after a map command calls the control
plane and the response is not successful. The line starts with map: and then
the command-specific error prefix.
What it means: the CLI reached the Forge control plane and the control
plane returned a non-success HTTP response. Use API errors to
decode the CLI prefix, HTTP status, code, and message.
Customer action: keep the exact command and full redacted response body.
Run map whoami to confirm the saved endpoint context. If the command is
app-specific, run map doctor --app <owner/repo>. Then use the
command-specific troubleshooting entry: onboarding, deploy request
rejection, missing deploy evidence, publish rejection, stale reviewed source,
or protected-app access.
Next command or log: map whoami, then map doctor --app <owner/repo>
when the command involved an app or repo. For deployment refs, run
map versions <app> to confirm the ref belongs to the app before retrying
map --json status <deployment-ref> or
map --json evidence <deployment-ref>.
Evidence to collect: exact command, HTTP status, response body with tokens
redacted, saved endpoint context from map whoami, repo owner/name, app ref,
deployment ref when present, and the command-specific evidence named by the
matching entry on this page.
Build and Runtime Readiness¶
Review blocks the deploy¶
Where you see it: Forge deploy status with ReviewBlocked, or
review_status: Blocked.
Probable cause: the reviewed manifest or source snapshot violates the
supported app contract. Common inputs to check are mithran.yaml, capability
kind, route declarations, runtime startup command, app_env policy,
public_edge, and secret-looking non-secret environment values.
Customer action: inspect review_gate, review_ref, failure_reason, and
map --json evidence <deployment-ref>. Fix the manifest or source issue at a
new commit and deploy again.
Next command or log: map --json status <deployment-ref>, then
map --json evidence <deployment-ref>.
Evidence to collect: deploy status, evidence output, mithran.yaml at the
failed commit, source SHA, and review finding text.
Build fails¶
Where you see it: Forge deploy status, custom-CI GitHub Actions log, or control-plane response with build stage failed.
Probable cause: the Dockerfile, build context, dependency install, or startup package metadata does not build successfully in the server-side builder.
Customer action: reproduce the build from the repo commit when possible, fix the Dockerfile or dependency issue, commit the change, and deploy again.
Next command or log: Forge deploy status, map --json status <id>, and
map --json evidence <id> when the control plane returned an ID.
Evidence to collect: deploy status, control-plane response, commit SHA, Dockerfile, package lockfile, build error text, and GitHub Actions run URL when custom CI is involved.
Runtime readiness fails / the app won't come up¶
Where you see it: Forge deploy status, custom-CI GitHub Actions log, or control-plane response with the runtime stage not ready.
Probable cause: the container is not listening on $PORT, the app returns a
non-200 response during Forge readiness checks, or the startup command in
mithran.yaml is wrong.
Customer action: make the app listen on $PORT, make the app's local
readiness paths return HTTP 200, align the Dockerfile and manifest startup
command, then redeploy. If those checks pass but Forge still reports runtime
health failure, use the build-or-runtime readiness packet in
Support and escalation.
Next command or log: map --json status <id>,
map --json evidence <id> when the endpoint has evidence, then the app's local
health check. Use HTTP app contract for local Docker
checks.
Evidence to collect: deploy status, control-plane response, Dockerfile,
mithran.yaml, startup command, expected port, serving probe behavior, and
GitHub Actions run URL when custom CI is involved.
map logs is not the deploy investigation source¶
Where you see it: local terminal after map logs <deployment-ref>.
Probable cause: Forge deploy investigations use status and evidence records.
Customer action: use map --json status <deployment-ref> and
map --json evidence <deployment-ref>. For build failures, inspect
build_logs_ref, build_failure_ref, and provider diagnostics in evidence.
For runtime failures, inspect runtime_failure, deploy evidence when the
endpoint has evidence, and the app's startup and serving probe behavior.
Next command or log: map --json status <deployment-ref>, then
map --json evidence <deployment-ref>.
Evidence to collect: deploy status, evidence output, build refs, runtime failure details, route status, and GitHub Actions run URL when custom CI is involved.
Routing, access, and publishing¶
unknown_hostname when you curl your app¶
Where you see it: terminal or browser when opening the published app
hostname, such as https://my-app.apps.mithran.cloud/ for an app served as
app:my-app.
Probable cause: the clean public URL has not been published, the route has
not propagated to the edge, the deploy did not reach route_status: Ready, or
the hostname does not match the served app ref.
Customer action: run map versions <app> to confirm the published record,
wait a few seconds, retry the hostname, then check deploy status for
route_status: Ready and confirm the hostname matches the app ref shown by
map versions <app>.
Next command or log: map versions <app>, curl against the exact
published hostname, then Forge deploy status.
Evidence to collect: app hostname, app ref, metadata.app_id, curl
output, deploy status, control-plane response, and GitHub Actions run URL when
custom CI is involved.
For the hostname model, see App access and sharing.
Access denied on a protected app¶
Where you see it: browser or API client opening a protected app route.
Probable cause: the user is not signed in, has an invalid session, or is
signed in but does not match the protected sharing policy. A missing or invalid
session is an authentication failure. A signed-in user who is not in
allowed_domains or share receives a protected-route denial.
Customer action: confirm the user is signed in, run map access plan, and
confirm the resolved policy includes the user, domain, or account: principal.
If the policy is wrong, update access.yaml, run map access apply, and
verify the intended hostname. The applied policy reaches a served route when
that route is updated or reconciled.
Next command or log: browser response, map access plan,
map access apply, app hostname, and map versions <app> when the clean
public URL is involved.
Evidence to collect: app hostname, user/domain needing access, observed
access-denied response, exposure value, access.yaml, plan output, apply
output, and tenant/app refs.
For exposure values and protected-app status, see App access and sharing.
Manifest exposure is not accepted¶
Where you see it: manifest review blocks the deploy with a
public_edge.exposure finding.
Probable cause: the deployed mithran.yaml uses an unsupported exposure
value. Manifest review accepts protected, none, public-redirect, and
public.
Customer action: check mithran.yaml at the failing commit and set
public_edge.exposure to one of those values. Deploy the reviewed commit again,
and publish the reviewed version when the clean public URL should move.
Next command or log: Forge deploy status and the failing mithran.yaml.
Evidence to collect: app hostname, mithran.yaml at deployed commit,
deploy status, publish command output when publish is involved, exposure value,
and observed response.
I deployed, but the clean public URL does not show the version I expected¶
Where you see it: browser or curl against the app hostname after a
successful deploy.
Probable cause: Forge separates deploying a version from publishing it to the clean public host. A deploy can succeed without moving the clean host.
Customer action: confirm the deploy succeeded, list versions with
map versions <app>, then run map publish <app> --version <version> for the
reviewed version that reached Succeeded or Promoted and should serve users.
Next command or log: Forge deploy status, map versions <app>, then
Versions and publishing.
Evidence to collect: deploy status, commit SHA, app hostname, published version expected, and observed app response.
Publish says the version is not publishable¶
Where you see it: local terminal after map publish.
Probable cause: the selected deployment ref does not point at a reviewed, succeeded internal version. The publish endpoint rejects blocked, failed, in-flight, or missing deployments.
Customer action: run map versions <app>, choose an internal version whose
deploy reached Succeeded or Promoted, and publish that version. If you only
have a deployment ref, inspect it with map --json status <deployment-ref>
before publishing.
Next command or log: map versions <app>,
map --json status <deployment-ref>, then
map publish <app> --version <version> --expected-sha <sha>.
Evidence to collect: publish command, CLI error, map versions <app>
output, deployment ref, deploy status, source SHA, and app hostname.
Publish reports a stale reviewed source¶
Where you see it: local terminal after map publish <app> --version
<version> --expected-sha <sha>.
Probable cause: Forge compared the selected deployment with the SHA supplied
as --expected-sha and rejected the publish.
Customer action: re-run map versions <app>, confirm the selected version
label or deployment ref is the one approved for release, re-check the reviewed
Git commit SHA, and retry only if the intended deployment and SHA still match
the release review.
Next command or log: map versions <app>,
map --json status <deployment-ref> for deploy state, and the publish command
with the exact --expected-sha value.
Evidence to collect: expected SHA, selected version label, deployment ref, publish command, and full CLI error.
Need to revoke app access¶
Where you see it: admin request to stop source access, deploy triggers, route serving, or protected-app sharing.
Probable cause: source access, deploy triggers, route serving, and protected access are separate controls.
Customer action: use App access and sharing to choose the right revocation step.
Next command or log: GitHub App settings, custom-CI workflow state when applicable, app hostname, and the route-retirement section in Support and escalation when the route itself must stop serving.
Evidence to collect: repo owner/name, app hostname, GitHub App grant state, custom-CI workflow state when applicable, and exposure value.
Still stuck?¶
Use Support and escalation after the customer-owned checks above. That page owns the escalation packet and support-owned request formats.