> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ohmyho.st/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> For account actions, read https://ohmyho.st/skills/ohmyhost-get-started/SKILL.md and use the authenticated ohmyho.st CLI or local product MCP. Mintlify search only reads documentation. Preserve the customer’s selected project, environment and authentication provider.

# Diagnose a deployment

> Diagnose build, health, runtime, browser, mail and cron failures; resume eligible operations and follow support replies.

Start with the current project and original operation:

```sh theme={null}
ohmyhost project context --project "$PROJECT_ID" --json
ohmyhost operation get "$OPERATION_ID" --json
ohmyhost logs "$OPERATION_ID" --follow --json
```

Read the stable error code, suggested action and any retry interval. Keep source-admission failures, build failures and pending DNS/mail separate.

| Result | Next action |
| - | - |
| Source blocker or conversion requirement | Inspect the exact source file/capability, fix it, push and plan that commit. |
| `progress.phase: waiting_for_mail` | Read `mail_status` (same as `mail_domain_status`) with the Prod environment ID; apply its required records. |
| `reconciliation.state: required` | Review the operation and perform one confirmed reconciliation. |
| `reconciliation.state: pending` | Wait and inspect the existing operation; do not submit another attempt. |
| `error.code: build_failed` | `operation get` names the failed deployment as `deployment_id`. Read its diagnostics: `ohmyhost deployment logs --project "$PROJECT_ID" --deployment "$DEPLOYMENT_ID" --follow --json` or MCP `deployment_logs`. The `BUILD_FAILED` item carries `excerpt`, the sanitized tail of your own install/build output (newest lines last; `excerpt_truncated` means earlier output was omitted). An ending ohmyho.st packaging: line names an output size/file limit. Fix that cause,push andplan the new commit. Without an excerpt,the build may have printed nothing,hit the eight-minute deadline or failed inside the platform; plan the same commit once more,then report both IDs if it repeats. |
| `error.code: runtime_candidate_failed` | The new deployment failed its health check. In the same deployment logs, the `HEALTH_CHECK_FAILED` item names the `route`, the `status_code` it answered and, for a project owner, an `excerpt` of the response. The check is a cookieless `GET` that follows no redirect, so a redirect fails too. Each probe has five seconds and follows no redirect; an ordinary login redirect fails. After promotion/rollback,first fix the target environment secret if that is the cause and plan again. For source errors,fix/push the new commit. If the probe throws or exceeds the timeout repeatedly,a diagnostic can be absent and the original operation may require reconciliation. A previous deployment keeps serving when the new candidate fails. |
| `error.code: runtime_candidate_rejected` | The runtime refused the built Worker script. Check the default export and imports of `src/ohmyhost/worker.ts`, then plan the new commit. |
| `error.code: storage_jurisdiction_conflict` | Match storage.jurisdiction to the immutable us/eu project region from project status,push andplan again; the project cannot move regions. |
| `error.code: database_migration_failed` | Read DATABASE\_MIGRATION\_FAILED's file/catalog reason; none of the new files applied. Preserve applied files and use later timestamps. Follow [expand-only admission](/migrations); never reset the database. |
| CLI 0.1.24 init/plan `managed_auth_mail_required` | Upgrade to CLI 0.1.25 or later. Older clients incorrectly required managed mail for Better Auth. Preserve your auth and chosen sender; only calls through ohmyho.st Mail need its capability, Paid access and verified sender. |
| App `402 Project execution paused` | Resolve Stop budget,expired seven-day credit grace,or custom hostname lacking Paid/flag eligibility. Serving resumes within about five minutes; redeploying cannot fund it. |
| App `429 Runtime limit exceeded` | Reduce work to fit50msCPU/ten subrequests; use small batches. This is not a request rate limit. |
| App `502 Upstream unavailable` | The app threw or failed to run; read that deployment's diagnostics. |
| App `503 Service unavailable` or `Credit check unavailable` | Address/credit/Dev check unavailable,or Dev passed about1,200requests/minute. Wait/retry; load-test Prod. |
| Non-GET/HEAD `403 Forbidden` | Verify Origin/cookies and the committed [browser/CORS declarations](/browser-security). |
| Server `403 Egress denied` or `502 Egress upstream unavailable` | Add the exact HTTPS origin to runtime.egress.allow,commit/deploy; redirects require the final URL.304 is preserved. |
| Cron absent or failed | Read function\_runs\_list or function runs with the actual environment ULID; state,attempt,status\_code describe the outcome. [Observe runs](/functions#observe-runs). |
| `response_contract_invalid`,or old MCP `client_request_failed` with working login | Compare installed CLI/MCP with [current release](https://ohmyho.st/client-release.json),upgrade both/reload MCP,then replay the original request/key. If current,report the request ID. |
| HTTP 429 | Respect `Retry-After`; do not fan out retries. |

## Reconcile only when requested

```sh theme={null}
ohmyhost operation reconcile "$OPERATION_ID" --idempotency-key "$RECONCILE_KEY" --yes --json
```

Use this when the operation reports reconciliation is required and no attempt is pending. Retain the same request key across uncertainty. A completed reconciliation attempt does not itself mean the original deployment succeeded.

## Read diagnostic pages

Deployment diagnostics/logs are retained seven days. CLI deployment logs reads one page of at most100 items despite --follow; MCP deployment\_logs takes cursor. Pass next\_cursor as cursor for older records. DEPLOYMENT\_FAILED carries no detail: follow the failed operation's suggested\_action. Operation logs is separate: CLI logs --follow has bounded reconnects/Last-Event-ID; operation\_stream\_ended means the original still runs,so poll operation get about every sixty seconds. No work was cancelled.

## Error codes

Act on code,retryable andsuggested\_action. Only CLI errors returned by the API add docs\_url; local CLI/MCP and terminal operation failures use their own guidance.

| Code | HTTP | Retry |
| - | - | - |
| [`api_key_creation_uncertain`](/errors/api-key-creation-uncertain) | 503 | Yes |
| [`api_key_permissions_unavailable`](/errors/api-key-permissions-unavailable) | 503 | No |
| [`billing_purchase_conflict`](/errors/billing-purchase-conflict) | 409 | No |
| [`billing_recharge_conflict`](/errors/billing-recharge-conflict) | 409 | No |
| [`cloudflare_authorization_closed`](/errors/cloudflare-authorization-closed) | 409 | No |
| [`cloudflare_zone_not_bound`](/errors/cloudflare-zone-not-bound) | 409 | No |
| [`compute_change_conflict`](/errors/compute-change-conflict) | 409 | No |
| [`compute_change_pending`](/errors/compute-change-pending) | 409 | No |
| [`compute_performance_paid_required`](/errors/compute-performance-paid-required) | 403 | No |
| [`compute_performance_unavailable`](/errors/compute-performance-unavailable) | 503 | No |
| [`confirmation_expired`](/errors/confirmation-expired) | 409 | No |
| [`confirmation_invalid`](/errors/confirmation-invalid) | 409 | No |
| [`data_change_blocked`](/errors/data-change-blocked) | 409 | Yes |
| [`data_change_in_progress`](/errors/data-change-in-progress) | 409 | Yes |
| [`data_change_not_applicable`](/errors/data-change-not-applicable) | 409 | No |
| [`database_access_limit`](/errors/database-access-limit) | 409 | No |
| [`database_write_pending`](/errors/database-write-pending) | 409 | No |
| [`deployment_plan_expired`](/errors/deployment-plan-expired) | 409 | No |
| [`deployment_plan_incompatible`](/errors/deployment-plan-incompatible) | 409 | No |
| [`domain_dns_conflict`](/errors/domain-dns-conflict) | 409 | No |
| [`domain_hostname_taken`](/errors/domain-hostname-taken) | 409 | No |
| [`environment_secret_mutation_blocked`](/errors/environment-secret-mutation-blocked) | 409 | Yes |
| [`etag_mismatch`](/errors/etag-mismatch) | 409 | No |
| [`forbidden`](/errors/forbidden) | 403 | No |
| [`framework_conversion_required`](/errors/framework-conversion-required) | 409 | No |
| [`github_connection_required`](/errors/github-connection-required) | 409 | No |
| [`github_connection_revoked`](/errors/github-connection-revoked) | 409 | No |
| [`idempotency_key_reused`](/errors/idempotency-key-reused) | 409 | No |
| [`insufficient_organization_credits`](/errors/insufficient-organization-credits) | 402 | No |
| [`interactive_login_required`](/errors/interactive-login-required) | 403 | No |
| [`invalid_request`](/errors/invalid-request) | 400 | No |
| [`mail_capacity_unavailable`](/errors/mail-capacity-unavailable) | 503 | Yes |
| [`mail_domain_conflict`](/errors/mail-domain-conflict) | 409 | No |
| [`mail_domain_required`](/errors/mail-domain-required) | 409 | No |
| [`migration_filename_noncanonical`](/errors/migration-filename-noncanonical) | 409 | No |
| [`organization_required`](/errors/organization-required) | 409 | No |
| [`paid_plan_required`](/errors/paid-plan-required) | 402 | No |
| [`payload_too_large`](/errors/payload-too-large) | 413 | No |
| [`powered_by_flag_required`](/errors/powered-by-flag-required) | 409 | No |
| [`production_deployment_required`](/errors/production-deployment-required) | 409 | No |
| [`project_budget_exceeded`](/errors/project-budget-exceeded) | 402 | No |
| [`project_domain_delete_required`](/errors/project-domain-delete-required) | 409 | No |
| [`project_export_not_ready`](/errors/project-export-not-ready) | 409 | No |
| [`project_handle_invalid`](/errors/project-handle-invalid) | 409 | No |
| [`project_handle_taken`](/errors/project-handle-taken) | 409 | No |
| [`project_handle_unavailable`](/errors/project-handle-unavailable) | 503 | Yes |
| [`project_handle_unchanged`](/errors/project-handle-unchanged) | 409 | No |
| [`project_identity_unavailable`](/errors/project-identity-unavailable) | 503 | Yes |
| [`project_notes_conflict`](/errors/project-notes-conflict) | 409 | No |
| [`project_rename_blocked`](/errors/project-rename-blocked) | 409 | Yes |
| [`promotion_invalid_target`](/errors/promotion-invalid-target) | 409 | No |
| [`promotion_source_stale`](/errors/promotion-source-stale) | 409 | No |
| [`promotion_target_stale`](/errors/promotion-target-stale) | 409 | No |
| [`rate_limited`](/errors/rate-limited) | 429 | Yes |
| [`reconciliation_exhausted`](/errors/reconciliation-exhausted) | 409 | No |
| [`repository_configuration_missing`](/errors/repository-configuration-missing) | 409 | No |
| [`repository_not_installed`](/errors/repository-not-installed) | 403 | No |
| [`resource_not_found`](/errors/resource-not-found) | 404 | No |
| [`rollback_target_data_changed`](/errors/rollback-target-data-changed) | 409 | No |
| [`service_unavailable`](/errors/service-unavailable) | 503 | Yes |
| [`shared_data_requires_promotion`](/errors/shared-data-requires-promotion) | 409 | No |
| [`source_commit_not_found`](/errors/source-commit-not-found) | 409 | No |
| [`storage_jurisdiction_conflict`](/errors/storage-jurisdiction-conflict) | 409 | No |
| [`unauthenticated`](/errors/unauthenticated) | 401 | No |
| [`workers_runtime_incompatible`](/errors/workers-runtime-incompatible) | 409 | No |

## Report a platform issue

If an error lacks a useful cause or the documented operation cannot continue, submit [feedback](/feedback) with the project/operation IDs, expected behavior and a short redacted reproduction. Do not paste tokens, secret values, raw environment files or customer records.

A provider observation failure means unavailable, not ready or zero usage. Keep customer source changes separate from a provider-capacity issue.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.