Troubleshooting & getting help
When something goes wrong, work it in this order: read the structured error, read the logs, read the relevant guide, then escalate.
Start with the error code, not the message
Every tool returns structured output. Failures carry a machine-readable code you can branch on — don't parse the human message. Multi-step tools (start_project, import_repo) return { ok: false, failedAt, partial } so you can resume from the exact step that failed rather than starting over.
A deploy failed (status: "error")
The build or deploy didn't complete. Read the build log:
get_logs({ applicationId, source: "build" })
This is the output of building and shipping the image — compile errors, failed installs, a bad Dockerfile. Fix in the repo, push_files, and the platform auto-deploys again. See deploymill://guides/logs for the full failed-deploy loop and log filtering (tail / grep / level / since).
The deploy succeeded but the app misbehaves
The image is running but the app is wrong at runtime. Read the container's own stdout/stderr:
get_logs({ applicationId, source: "runtime" })
(Runtime logs need the optional log-reader sidecar configured; without it this degrades to { configured: false }.)
The health gate is failing / auto-rollback fired
Deploy, rollback, and auto-rollback all key off one health endpoint (default /healthz) that must return 200 iff fully healthy — anything else (non-200, connection error, timeout) counts as unhealthy. If deploys keep rolling back, your health handler is the first suspect: make sure it actually returns 200 once the app is ready (DB reachable, migrations run). Full contract in deploymill://guides/health.
Common error codes
| Code | Meaning | What to do |
|---|---|---|
dns_not_pointed | A custom domain's DNS isn't pointed at the ingress yet | Point the record at CUSTOM_DOMAIN_TARGET, then retry |
invalid_hostname / reserved_hostname | The host is malformed or reserved | Choose a different host |
host_claimed | Another org already verified that host | Use a host you control |
active_app_limit_reached | Your org is at its app quota | Delete an unused app or check get_account |
preview_app_limit_reached | At the TTL-preview quota | Let previews expire or delete some |
storage_limit_reached | A volume would exceed the storage quota | Lower the requested size or free space |
support_not_configured | The support backend isn't wired on this server | Ask the operator, or use the contact link |
Call get_account for a read-only view of your quota headroom before a workflow.
DNS and custom domains
Point the domain's DNS at CUSTOM_DOMAIN_TARGET first, then declare it under domains.custom in .deploymill/project.json and run reconcile_project — it validates DNS and issues the certificate. Declaring it in the config (rather than a one-off attach_domain) means it survives future reconciles.
When the docs run out
If you've read the structured error, the logs, and the relevant guide and you're still stuck, escalate. Use the support avenue surfaced in your account, and include the failing tool, the code, and the applicationId — that context is what lets a request be answered quickly. Never paste secrets or connection strings into a support request.