Skip to content

Troubleshooting a deploy ​

Each section is one state the dashboard can show you, why it happens, and the one thing that moves it forward.

Prompt for your agent

Copy this into Claude Code, Cursor or any agent that can run shell commands. Most of these states are fixed in your browser; the agent finds out which one you are in, says the words, and checks the result.

text
Read https://docs.stasho.xyz/guides/troubleshooting.md. My Stasho deploy is stuck or failed:
<what the dashboard shows, or the project id>. Find the matching section. If my agent key is in
the STASHO_AGENT_KEY environment variable, run stasho with npx @stasho/cli to read the project
and its deployments; for a repo I name, read the workflow run with gh. Fix what is yours to fix
in the repo. For anything in the dashboard, tell me the page's words one step at a time and wait
for me. Verify the outcome with a read, not my word. Never ask for my wallet key, my seed phrase,
a GitHub token or an agent key in chat.

Setup pending ​

What you see: the project or repo card reads Setup pending and the project page shows Finish setup.

Why: importing a repo opens a pull request that adds the deploy workflow. Nothing deploys until that PR is merged.

Do this: open the project page and click Merge & deploy, or merge the PR on GitHub. A monorepo import opens one PR for all selected workspaces.

App VM not online ​

What you see: a server app deploy rests at Pinned with "Your App VM has not come online yet".

Why: the bundle is published, but the App VM that should run it has not reported in. Either you have no App VM yet, it is still being prepared, or preparing it failed.

Do this: open App VM in the sidebar.

  • No VM yet: create one. Your server apps deploy on it once it comes up.
  • Preparing: the page shows each stage. It usually takes about 6 minutes; if it runs past 20 minutes, the page offers to delete the VM and start over.
  • "We could not prepare your VM.": click Try again if it is offered (your SSH keys are filled in), otherwise Delete and create a new one.

The pinned deploy installs itself once the VM reports.

App VM running but not reachable ​

What you see: a server app deploy rests at Pinned with "Your App VM is running, but Stasho cannot reach it". This shows once Stasho has failed to reach the VM for five minutes in a row. The App VM page's status card reads "Running, but Stasho cannot reach it."

Why: the VM is running, but the network of the host it runs on is not routing traffic to it. Stasho cannot see the VM, so the deploy can't be confirmed live, and visitors likely can't reach it either. Re-checking will not change that.

Do this:

  1. Check status.stasho.xyz first. If Stasho itself is having an incident, wait for it to clear.
  2. Otherwise, wait. Stasho restarts the VM, and if it stays unreachable it moves the VM to a new host on its own: the status card says it is moving your VM to a new host (about 10 minutes), and your apps redeploy there. You get an email when the move is done, or one saying the VM is down if it failed, in which case the status card offers Create a new VM. See When your VM moves.

Not a site ​

What you see: a workspace in the import list is greyed out with "Not a site: no build script and no index.html".

Why: the folder has nothing Stasho can serve. Library packages (packages/shared, packages/utils) and workers usually look like this.

Do this: import only the workspaces that are sites or server apps. If the folder really is a site, add a build script to its package.json or an index.html at its root, push, and start the import again.

Next.js server app on the static target ​

What you see: saving Settings is refused with "A Next.js server app can't deploy as a static site".

Why: a Next.js app without output: "export" builds server code, not static files. Publishing its .next/ folder serves nothing and is usually over the size limit.

Do this: either keep Server app (App VM) as the deploy target, or add output: "export" to next.config, push, then Re-detect in Settings so the framework becomes Next.js (static export) and the output directory becomes out. Save, then on the card that appears click Merge & apply (Merge & deploy if the project has never deployed), or merge the PR on GitHub. The merge starts the new build, so don't click Redeploy. Pages that use SSR or API routes will not work as a static export.

Deploy target changed ​

What you see: a deploy reads Failed with "Deploy target changed".

Why: you switched the project between static site and server app. The earlier deploy was built for the other target and can no longer be served.

Do this: merge the settings PR: Merge & apply on the Settings tab, or on GitHub. Its merge builds for the new target. Click Redeploy only if no PR is open: with one open, a Redeploy builds from the old workflow file.

Build too large ​

What you see: a deploy fails with "Build is N MB, the limit is 200 MB" or "Build has N files, the limit is 10000".

Why: static deploys are capped at 200 MB unpacked, 50 MB compressed, and 10000 files. A build that large usually includes something that is not the site: a framework cache, source maps, or node_modules.

Do this: check the Output directory in Settings points at the built site (dist, out, build), not the project root or a framework work folder like .next. If it was wrong, fix it and Save, then merge the settings PR: Merge & apply on the card, or on GitHub. The merge starts the new build, so don't click Redeploy. If it was right, trim the build in your repo and push.

No token from GitHub ​

What you see: a deploy fails with OIDC_TOKEN_FETCH_FAILED. The Actions log shows lines reading OIDC token fetch failed: HTTP 500, ... before it.

Why: each deploy step asks GitHub for a short-lived token to prove which repo it runs for. The step asks up to five times, which takes about 30 seconds, or about 3 minutes when GitHub doesn't answer at all, then stops. That is nearly always an incident on GitHub's side.

Do this: re-run the job in GitHub Actions once githubstatus.com is clear. If Report failure also lost the token, the deployment shows as stuck until the backend marks it failed, or, if the first step lost it too, no deployment appears at all.

A workflow file from before this check fails with jq: parse error instead. To update it, change a build setting in the project's Settings and save, change it back and save again, then merge the pull request that opens.

Working with an agent ​

An agent reads a stuck deploy; most of the fixes are yours. Nothing on the agent API merges a PR, changes a setting or touches a VM. A key's reads carry the status and the runId, never the error text, which is encrypted to you: the cause comes from the Actions log, with gh signed in to an account that can read the repo.

bash
npx @stasho/cli deployments --project $PROJECT_ID
gh run view $RUN_ID --repo $OWNER/$REPO --log-failed
StateWhat the agent readsWho moves it
Setup pendinggh pr list --repo $OWNER/$REPO --author app/stasho-deploy shows the open PR; stasho deploy exits 3 saying the deploy workflow is not set up; the deployment list is emptyyou merge, or the agent if it can merge on GitHub
App VM not online, or not reachableThe entry reads pinned; the VM's status document on :8443 answers or does notyou, on the App VM page; Stasho moves an unreachable VM on its own
Not a siteThe folder's package.json and files, in the repothe agent, if it can push and the folder really is a site
Next.js on the static targetnext.config in the repothe agent adds output: "export" if the app has no SSR or API routes; you Re-detect, save and merge the PR
Deploy target changedThe entry reads failed; gh pr list shows whether a settings PR is openwith a PR open, you merge it, or the agent if it can merge on GitHub, and that starts the build; with none, the agent first reads the workflow file, because a failed sync leaves the old recipe there (Upload artifact builds a static site, Package bundle a server app); if it matches the new target, the agent with a deploy key runs stasho deploy, else you click Redeploy
Build too largeThe Actions log names the size or the file countyou change Output directory and merge the PR; the agent can trim the build in the repo

stasho deployments needs the read scope, and stasho deploy the deploy scope.

What the agent hands you, in these words, with the section that matches:

text
Open the project in the Stasho dashboard.
Setup pending: on the Finish setup card click Merge & deploy.
App VM: click App VM in the sidebar and tell me what the status card or panel reads, and paste me
the IPv6 host from the Access card if one shows. If it reads "We could not prepare your VM.",
click Try again if it is offered, otherwise Delete this VM and start over.
Next.js on the static target: open the Settings tab, click Re-detect from repo, Apply, then Save.
Then on the card that appears click Merge & apply (Merge & deploy if the project has never
deployed). The merge starts the build, so do not click Redeploy.
Deploy target changed: on the Settings tab click Merge & apply. If no card shows, tell me: I check
the workflow file before you click Redeploy.
Build too large: on the Settings tab set Output directory to <dir> and Save, then click Merge &
apply on the card. Do not click Redeploy.
Tell me when it is done, and what the deployment reads now.

How the agent verifies it afterwards. The same reads: with a key, stasho deployments --project $PROJECT_ID until the new entry reads live (an App VM app can rest at pinned while the VM picks it up). With no key, the run list and a fetch of the gateway URL you paste. A monorepo workspace's workflow file carries a suffix after stasho-deploy.

bash
gh run list --repo $OWNER/$REPO --workflow stasho-deploy.yml --limit 3