Skip to Content
API 參考錯誤碼對照表

錯誤碼對照表

通則

  • 404 = 未授權或不存在。sandbox 刻意「不洩漏存在性」:沒權限、別家公司的 id、受限 key 動了禁區,全都回 404 而非 403。
  • 403 是真實例外,不是預設。 建立呼叫者不能擁有的 department/company 任務 → owner_scope_forbidden。Writeback 發布/提交閘與預算 hold 也是 403。送 owner_scope=chatroom 是 422,不是 403。
  • 422 = 請求驗證。未知欄位(extra="forbid")、pattern 不符、大小超限、缺必帶 header。預算/hold 定價拒絕也可能是 422。
  • 409 = 狀態衝突。非法狀態轉換、樂觀鎖 CAS 不符、digest 不符、不可重試、版本容量耗盡。
  • 413 = body 過大。提交執行時依 Content-Length 先擋。
  • 503 = kill switch。SANDBOX_ENABLED=false 時的變更(預設 true)。

對照表

狀態碼錯誤 / 情境何時發生
403受限 Sandbox 金鑰/缺聊天室路徑/invalid scope認證層字串,不是 {code}。只發生在 /private/module/sandbox/environments*、/tasks*(含每任務歷史 /tasks/{id}/runs)、/root*、/chatrooms/{id}/quick-run、路徑裡完全沒有 chatroom 片段的路由(/settings、/bindings*、/secrets*、/secret-approvals*),以及路徑上的 chatroom id 不在金鑰的 allowed chatrooms 時。
405受限 Sandbox 金鑰動了 scope allowlist 以外的其他 sandbox 路由granted-jobs(含 enable/disable)、runs/{id}/retry、runs/{id}/{log|output}/public-link 由 scope 檢查直接回 405 Method Not Allowed——不是 403 也不是 404。
403Insufficient permissions.settings 與每任務歷史的 COMPANY_MANAGER 閘(非 manager JWT)。
404未授權 / 跨公司 / 資源不存在sandbox router 內的藏存在性預設
404產出物 deletion_state != active 的 download下載已刪/墓碑產出物
403owner_scope_forbidden建立呼叫者不能擁有的 department/company 任務。這是用 404 藏存在性的例外。
403chatroom_owner_scope_removed若 chatroom 目錄建立繞過 enum 進到 CRUD(HTTP POST /tasks 先是 422)。
403output_policy_author_denied表格 writeback:發布者對目標表沒有不受限寫入權。Command 輸出(v5.21.0):撰寫者、發布者或提交者沒通過身分、grant 或範圍檢查;該 Command 不再是帶 effect_identity 的 restricted definition-authority Command(發布時是下面的 409);或提交 run 的方式不符合任務輸出交給自訂表格 Command的規則(什麼都不會排隊)。run 進行中該授權被收回時,command-output 端點也回這個。
403writeback_authority_denied提交者不能鑄 writeback 憑證。
403budget_reservation_exceeded提交執行/佇列建置時,定價 envelope 放不進公司配額;不建 row
422idempotency_key_required提交/重試/quick-run/secret 寫入缺 Idempotency-Key
422欄位驗證未知欄位、owner_scope=chatroom(enum)、digest pattern、缺少 owned_object_id+source_digest、canonical JSON 超限、空 PUT body
422output_policy_invalid/output_policy_table_not_found/output_policy_channel_table草稿/發布時 writeback policy 不合法
422output_policy_governed_table草稿建立/更新:表格 writeback policy 指向 write_policy 為 commands_only 的表(v5.21.0)。發布與提交 run 時,同樣的狀況是 409 output_policy_unsatisfiable
422output_policy_command_not_found/output_policy_schema_mismatchCommand 輸出 policy(v5.21.0),草稿建立/更新時,以及提交 run 時再次檢查:你公司裡沒有這個 id 的活 Command,或 input_schema 與 Command 的 inputs 不同/該 Command 不是寫入型
422預算/hold 定價拒絕提交時定價或 hold 驗證失敗,例如 no_active_region、missing_price、invalid_envelope、missing_window
422timeout_exceeds_ceilingtimeout_seconds > 公司 timeout_ceiling_seconds
422job_contract_invalid在草稿建立/更新時(POST /tasks/{id}/versions 或 PATCH .../versions/{vid})——發布時絕不會出現:input_example 不是合法 JSON、不符合版本自己的 input_schema;work_command 含 NUL/超過 4096 UTF-8 位元組;或 input_schema 本身不合法——不是 JSON、不是 JSON object、超過 64 KiB(UTF-8 位元組計,非字元數)、含 NUL、或不是合法的 draft 2020-12 schema。回應的 detail.errors 會一次列出所有問題(最多 20 筆)
422input_schema_violation提交執行時:input 不符合已發布版本的 input_schema。在派工前就拒絕。只有存好的 schema 本身解析不出來或拿不到時才會 fail-open(放行、記警告)
422input_not_stageablePOST /chatrooms/{cid}/runs:input JSON 無法 canonicalise 或寫入耐久儲存。發生在房間/版本授權之前,所以不會建出 run。run input 不再計入公司每分鐘 5 次上傳起始額度(後端 ≥ #1140),連續提交會被接受而不是拒絕。自 v5.10.11 起 POST /chatrooms/{cid}/quick-run 也會暫存 input,可能在 manager 檢查之後、建立任何任務或 run 之前回這個
422build_region_unavailablePOST .../versions/{vid}/builds:build_region 不在該部署公開的目錄內(託管雲端的 onprem;地端部署的任何雲端代碼),或地端已有 active 區域列、但指定的不在其中。什麼都沒排入
422bundle_path_forbiddenPOST /tasks/{id}/bundle-uploads:封存檔根目錄含 runner 保留檔名(startup.sh、work.sh、driver.sh、input.json)、絕對路徑或磁碟機絕對路徑、含 NUL/反斜線的路徑;訊息會寫出是哪個條目(後端 ≥ #1140)
409task_not_shared_to_roomPOST /chatrooms/{cid}/granted-jobs/{task_id}/enable:任務存在,但沒有分享給這個聊天室(或其部門/公司);訊息會寫出該呼叫哪條分享 API。#1140 之前是單純的 404
409task_bundle_runner_unsupported發佈或執行帶 bundle 的任務版本,但環境的 runner release 未核准(版本上 runner_release_approved=false;後端 ≥ #1162 直接讀 operator 核准表)。解法:重新排一次環境建置(會帶上目前的 runner),或請 operator POST /root/sandbox/runner-releases。照 runner_release_next_action 做
422script_too_large/script_not_utf8/script_contains_nulPOST /tasks/{id}/script-uploads 或 POST .../versions/{vid}/script-file 的檔案有問題
422secret_slot_policies_invalidPOST /tasks/{id}/shares 的 secret_slot_policies map 格式不對(slot 名不合法、政策值不合法、或超過 100 筆)
413request_too_large提交執行 body 依 Content-Length 過大
413context_too_largeContext PUT body/Content-Length 超過 declared_bytes
400invalid_content_lengthContent-Length header 不合法
409build_not_eligible版本 state 無法開始建置
409nonterminal_exists此版本已有未終態的建置 attempt
409not_cancellable建置已終態。cancel_requested/cancelling 冪等
409retry_not_eligible重試一個不在 {completed, customer_failed, platform_failed, cancelled} 的 run,或 POST .../versions/{vid}/retry-build 時版本 state 不是 retryable_failed
409retry_window_expired建置重試超過 7 天窗
409provisioning_retry_not_eligiblePOST .../versions/{vid}/retry-provisioning:版本 state 不在 regional_provisioning/provisioning_blocked/ready
409task_version_digest_mismatchsecret 授權的 digest 與已發布版本不符
409task_version_not_publishedPOST /secret-approvals(與別名 /shared-task-secret-approvals):task_version_id 指到的版本存在但不是 published。這道檢查在 digest 比對之前
409share_already_livePOST /tasks/{id}/shares:此 task + target 已經有一筆 live grant。要換 secret_slot_policies 必須先 revoke 再重新分享(新 generation)
409policy_version_conflictPUT /settings CAS 不符
409idempotency_conflict同一把 Idempotency-Key,不同 request hash
409active_environment_limit公司撞上 active 環境上限(預設 30)
429sandbox_queued_run_limit提交/重試(以及 Agent 與自訂表格 trigger 路徑)的公司 queued-run 上限:政策預設 100;地端部署取它與主機每公司上限(預設 20)中較小者。Quick Run 不看政策上限,但受地端上限約束。body detail = { code, message, limit }(SandboxQueuedRunLimitErrorResponse)。什麼都沒排入
429queue_full僅地端:整個 executor fleet 的佇列已達上限(預設 200)。body detail = { code, message, limit, retry_after_seconds }(SandboxQueueFullErrorResponse),另有 Retry-After: 60 header。什麼都沒排入——等過這段時間再重試
429staging_slot_exhausted20 個 live context-upload slot 或 20 GiB 宣告 staging。未完成上傳會漏 slot 直到 abort;連 scan report 寫入也會卡住
429upload_rate_limited每公司每分鐘超過 5 次 context-upload init
409(非法狀態轉換 / CAS)發布/歸檔非法轉換
409content_scrubbed_irreversible/version_not_runnable提交執行時版本非 published+content active(_refuse_not_runnable):content_state=scrubbed 回 content_scrubbed_irreversible(永久不可執行);其他任何非 published+active 組合回 version_not_runnable
409version_allocation_exhausted公司無法再分配一個 capacity-retained 版本(沒有已確認的區域配額/cap 為 0)
409capability_fenced上傳 capability 對不上這個 session
409output_policy_owner_scope_unsupported公司擁有的任務試圖發布 writeback 或 Command 輸出 policy
409output_policy_unsatisfiable發布時,或提交且真的鑄出憑證時,writeback 表已不在/有 channel rule/是 commands_only;Command 輸出 policy 則是發布時任何一項 Command 檢查失敗(查找、輸入與模式、restricted definition authority 且有 effect_identity)——對發布者與已記錄撰寫者的身分、grant 與範圍檢查仍是 403 output_policy_author_denied
503sandbox_disabledkill switch 下的變更(SANDBOX_ENABLED=false;預設 true)。/cancel、/download 仍可用
503sandbox_secret_pepper_missing / sandbox_infisical_unconfiguredsecret 寫入時 adapter/pepper 掛了
503capability_unavailable/storage_unavailable上傳 capability 或物件儲存掛了
503input_staging_unavailablePOST /chatrooms/{cid}/runs(自 v5.10.11 起還有 POST /chatrooms/{cid}/quick-run):暫存 input 的物件儲存不可用。手動提交在房間/版本授權之前暫存,Quick Run 在 manager 檢查之後;兩者都不會建出 run
503build_admission_fencedPOST .../versions/{vid}/builds 與 POST .../versions/{vid}/retry-build:平台正在做 stage-image rollout,建置 admission 被全域圍欄擋住(數分鐘)。body 是 { code, message, retry_after_seconds },同值也放在 Retry-After header;沒有任何東西被佇列,照 Retry-After 重試即可
503sandbox_writeback_key_unavailable宣告了 policy 但 HMAC key 缺失/太短

Secret 傳輸加密錯誤(回應形狀不一樣)

POST /secrets 與 POST /secrets/rotate 用 pydantic model validator 驗證 encrypted_value,所以這四個不是本頁其他地方那種 {"detail": {"code": "..."}} 形狀——它們回的是 FastAPI 標準的驗證錯誤陣列,slug 在 detail[].type(也會鏡射進 detail[].msg,精確等於 validation_error:<slug>,input/ctx 會從回應裡剝除):

Slug(detail[].type)原因
sandbox_plaintext_value_rejected送了非空的明文 value 欄位(不論有沒有一起送 encrypted_value);空字串或 null 的 value 會被忽略,不算明文
sandbox_encrypted_value_requiredencrypted_value 缺失或為 null
sandbox_transit_keypair_missing伺服器沒設定解密金鑰對
sandbox_encrypted_value_undecryptable信封形狀合法但解密失敗

四個都是 HTTP 422。Client 端加密流程見 Secret 與授權。

不是 REST 錯誤:share_grant_revoked

share_grant_revoked(409)只會出現在 runner 呼叫的控制面 manifest 揭露路由上——絕不會出現在 /private/module/sandbox 的租戶端點。當一個 owner 出借的 secret pin,其分享 grant 在 run 認領之後、到後續某次 manifest 讀取之間死掉了(撤銷、重新分享成新 generation、或 authority 變動),就會觸發這個。前端不會直接收到這個代碼,只會看到對應的 run 以失敗終結。見 Secret 與授權。

不在 /private/module/sandbox 底下:command-output 端點(v5.21.0)

POST /public/module/custom_tables/callback/command-output/{token_id} 是 Command 輸出 run 的 work script 拿密封憑證去呼叫的公開端點。它回 {"detail": {"code": "..."}}:404 output_run_unavailable(憑證不存在,或 Bearer secret 錯誤/缺少)、409 output_run_unavailable(憑證已撤銷或過期、run 已不在進行中,或它的任務或版本不再是 active 且已發布)、409 output_command_stale、409 output_command_conflict、422 output_schema_violation、403 output_policy_author_denied;body 格式不對或 token_id 不是 UUID 時,則是 FastAPI 的 422 validation 陣列,Command 執行本身也可能帶來它自己的錯誤。各代碼的意義見任務輸出交給自訂表格 Command。

Agent 工具錯誤(非 REST)

五個工具回 { "status": "error", "error": "<code>", "message": "..." }:

error何時
unauthorized重新授權/擁有權(SandboxAgentAuthError),或提交遇到 401/403 拒絕(例如 Command 輸出的規則)
validation_error參數不合法,或提交遇到 400/409/422 拒絕
forged_receipt收據不是簽過名的多段格式(必須含 4 個點)
not_found過期/別人的/隱藏/同一輪/已用過的收據
confirmation_rejected其他閉形式確認失敗
already_committed提案已經變成 run
proposal_not_pending狀態不是 prepared
same_turn / not_later / receipt_reused同一輪、不夠晚、或確認輪次已用過
retryable暫時性 commit;提案留在 prepared
confirmation_input_unavailable確認已驗證;耐久 input 無法重放。不建 run;提案仍 pending
provider_unavailable控制面不可用,或工具沒有對應到其他代碼的提交拒絕——包括兩種 429(sandbox_queued_run_limit、地端的 queue_full)
internal_error未預期;泛用訊息

見 Agent toolkit。

前端處理建議

  • 404:別假設是「不存在」——先確認權限、公司、key scope、id 是否屬於當前使用者。
  • 403 owner_scope_forbidden:換一個呼叫者能擁有的 scope,或換有該 scope 管理權的人。
  • 403 budget_reservation_exceeded:公司配額蓋不住這次 envelope;提示額度,不要重送同一請求。
  • 422 缺 header:補 Idempotency-Key(每次新意圖用新 UUID,重試沿用)。
  • 409:重新讀取資源目前 state 再決定下一步(別盲目重送)。
  • 409 version_allocation_exhausted:沒有已確認的區域配額或 cap 為 0——這是營運/配額問題,不是租戶少填欄位。
  • 503 sandbox_disabled:kill switch 關掉了(SANDBOX_ENABLED=false;預設開)。提示使用者稍後再試,取消/下載仍可用。
  • 418:Authorization 與 X-Api-Key 都沒帶(共用 TeamSync credential 例外,Could not validate credentials,發生在 sandbox 404 隱藏之前)——不是 401;見認證。
  • 租戶面的 429:sandbox_queued_run_limit、queue_full(地端;遵守 Retry-After)、staging_slot_exhausted、upload_rate_limited。退避;不要對 init 空轉重試。503 以外的 5xx 是平台失敗——退避重試;除非你還握著 Idempotency-Key,否則不要假設 run 沒建出來。

v5.10.0 新增的驗證與重試情況

  • 422 detail[].type = sandbox_value_too_short:create/rotate 解密後少於 4 個 UTF-8 bytes。
  • 409 task_version_not_published:明確 secret 核准指向未發布版本。
  • 409 retry_input_unavailable:無法重放保留的來源 input,請傳明確 input。
  • 核准 slot 集合非法/空白,或作者宣告使用保留 slot 名稱時,回 422 驗證錯誤。

請使用目前 OpenAPI 的 wait_reason、error_code、failure_stage 與 failure_source 型別。Provider 拒絕在重試處理後仍保留實際且已遮罩的來源資訊,不要自行轉成沒有內容的成功狀態。

Last updated on