Skip to content
Console →
Website →
Asking an AI? Paste this URL https://keelson.dev/llms.txt

Troubleshooting

Remember one thing first: give the error’s code and hint to your AI agent. Keelson errors are designed so that agents can read them and make the necessary correction. If you investigate the problem yourself, check the following in order.

Terminal window
keelson status # App and latest deployment status
keelson diagnose <deploy_id> # Diagnose a failed deployment
keelson logs deploy <deploy_id> # Progress logs and details of a failed deployment
keelson logs app <slug> # App standard output and standard error

When a deployment fails, keelson logs deploy also shows the saved details. If the app exits during startup, its stored startup logs preserve the traceback or process error for that deployment. Read them with keelson logs deploy <deploy_id> or keelson diagnose <deploy_id> before checking the listening port and health.path. The same commands can be used later to investigate dependency or Dockerfile build failures, unset secrets, and configuration or migration errors. Build output from successful deployments is not saved. If there are no progress logs or saved failure details to show, the command only explains why no logs are available.

In the console, the app page has a failure summary under Overview, deployment logs under View logs on Deploys, and app logs under Logs.

Where it stoppedWhat to inspectCommon causes
Before upload (CLI preflight check)Command outputMissing go.mod for a Go app; a Node app with only a pnpm or yarn lockfile; pip install in command; missing db.mode; unquoted env values
Validationcode and messageRetired workers or databases fields; reserved names; plan limits
BuildDeployment logsDependency resolution failure; mismatch between package.json and package-lock.json; private registry; build script error
StartupStored startup logs in keelson logs deploy <deploy_id>Not listening on 0.0.0.0; hard-coded PORT; exception caused by an unset secret
Health checkStored startup logs, then app logsThe app exited during startup; / returns 5xx; startup takes more than 120 seconds
MigrationDeployment logsSQL error in db.migrate. The previous revision continues running
Running but not behaving as expectedApp logs and access logsSee Runtime problems below

Ctrl-C stops only this client from watching. The deploy is still running server-side and may still become the active version. Use the deploy_id shown by the CLI to check its progress:

Terminal window
keelson status <deploy_id>

If you do not want the new version, wait for the deploy to finish and then return to the previous completed deploy:

Terminal window
keelson rollback --app <slug>

If the app has no earlier completed deploy, stop it after the deploy finishes:

Terminal window
keelson app stop --app <slug>
  • Listening on localhost — change it to 0.0.0.0
  • Hard-coding the port — read the PORT environment variable
  • Depending on files that only exist locally — such as .env, a local database file, or files covered by .gitignore. Check archive.excluded in the output of keelson deploy --check --json to see what was excluded
  • Environment variables are not set — values that exist only in your local .env are not available on Keelson. Declare them in secrets and set their values
  • Using file-based SQLite — neither /data nor /tmp is persistent. Move the data to Managed SQLite

Keelson’s Node builder uses npm, so dependency pinning requires npm’s package-lock.json. Run npm install in the project root, commit the generated package-lock.json, and deploy again.

You do not need to delete pnpm-lock.yaml or yarn.lock. The app can be deployed with either file alongside package-lock.json, and the build uses package-lock.json.

Check whether you are writing to a local file. Files in /tmp, /data, and the app directory are lost on restart, redeployment, or an idle stop. Store the data in a database or with the Files / Media SDK.

Work after a response is returned, in-app timers, and threads do not run. Finish the work synchronously within the request or move it to crons. See Scheduled Jobs.

  • Check whether the schedule is shorter than the plan’s minimum interval (it is rejected during deployment)
  • Check whether the previous run is still in progress (overlapping runs are skipped)
  • Check whether the monthly execution limit has been reached (remaining runs for the month are skipped)
  • Check whether the app is suspended
  • Check the run history on the Scheduled Jobs tab for the reason it was skipped

The cause is the browser cache. Confirm that the deployment has finished, then perform a hard reload (Mac: Cmd + Shift + R; Windows: Ctrl + Shift + R). A static-site redeployment takes 25–30 seconds to propagate to the edge.

A user says “I can’t access the app”

Section titled “A user says “I can’t access the app””
  1. Are they a workspace member, and have they accepted their invitation?
  2. Are they blocked?
  3. Are they in a group with permission to view the app?
  4. Are they signed in with the registered account?
  5. Are they denied by IP access controls? The 403 page shows the source IP.

See Members and roles for details.

This means the concurrent App Slot limit has been reached. Apps accessed in the last 5 minutes use a slot. Wait about 5 minutes, enable priority start for an important app, or upgrade your plan.

The app did not start its response within 120 seconds. Shorten the operation, send headers first by streaming, or move heavy work to crons. Server-side work may finish even after a 504 response, so make write operations idempotent.

  • Check whether the path is declared in auth.endpoints (it must start with /api/webhooks/ or /api/external/)
  • Check whether the method matches the declaration
  • Check whether the token scope and allowed IP addresses match

See External integrations.

Secrets are injected at deployment time. Redeploy the app or select Apply in the console.

If you receive a platform error such as deploy.platform.error, or if the steps above do not solve the problem, include the deploy_id (available from keelson status --json) when you contact us.