# Error Reference

## Deploy errors

| Code | Meaning | Fix |
|---|---|---|
| MISSING_MAIN | main.ts not in files | Add main.ts with export default handler |
| DEPLOY_ERROR | Provider rejected deploy | Check project_id exists; retry |
| NO_FILES | deploy() called with no staged files | Pass files directly or call stage_files first |

## Runtime errors (visible in check_app / get_app_logs)

| Symptom | Cause | Fix |
|---|---|---|
| status: 0, "context deadline exceeded" | Deno.serve() in main.ts or startup crash | Change to export default handler |
| status: 0 after correct pattern | Machine stopped after crash | Check get_app_logs for the actual error |
| status: 500 | Unhandled exception in handler | Fix the error shown in get_app_logs |
| DB connection timeout | ssl: true or bad URL parsing | Use the pgConfig() pattern from docs/database |

## Project errors

| Code | Meaning | Fix |
|---|---|---|
| NAME_TAKEN | Project name already used globally | Choose a different name |
| RESERVED_NAME | Name is reserved (admin, api, www…) | Choose a different name |
| PROJECT_NOT_FOUND | project_id does not exist | Call create_project first |
| PROJECT_LOCKED | The owner locked this app; mutations are blocked | Do NOT retry. See "Locked apps" below |

## Locked apps

The owner can **lock** an app from the web dashboard. While locked, every mutating tool returns
`PROJECT_LOCKED` and refuses the change: `deploy`, `edit_file`, `stage_files`, `execute_sql`,
`apply_migrations`, `rollback_to_version`, `upload_asset`, `delete_version`, `delete_project`, and
`apply_changes` (onto the locked main app).

`PROJECT_LOCKED` is **not retryable** — re-running the tool will fail again. There is intentionally
**no tool to unlock**: only the human owner can unlock, and only from the dashboard. When you hit
it:

1. Tell the user the app is locked and that they must unlock it from the dashboard (the error's
   `Hint` contains the URL). Do not loop or retry.
2. If they want to keep working without unlocking, offer a **draft**: `create_draft` works even on
   a locked app, so you can iterate in the private copy. Applying it back
   (`apply_changes`) still requires the main app to be unlocked first.

These operations are **always allowed** on a locked app: all reads (`check_app`,
`read_project_files`, `query_sql`, `get_app_logs`, `get_exceptions`, `list_versions`…),
`create_version`, `fork_project`, and `create_draft`.

## Validation errors

| Code | Meaning | Fix |
|---|---|---|
| VALIDATOR_UNAVAILABLE | Deno not available on server | Skip validation, deploy directly |
| VALIDATOR_TIMEOUT | Validation took >60s (large deps) | Retry; deps are now cached |

## Logs errors

| Code | Meaning | Fix |
|---|---|---|
| LOGS_ERROR | Cannot fetch logs | Wait a few seconds and retry; machine may be starting |
