fix(kiloclaw): return 404 instead of 500 for Instance-not-provisioned errors#1851
Merged
jeanduplessis merged 2 commits intomainfrom Apr 1, 2026
Merged
Conversation
…d" errors Custom error properties like .status are lost when errors cross the Cloudflare DO RPC boundary. statusCodeFromError() then defaults to 500 for "Instance not provisioned" / "Instance not running" errors that are semantically 404. This causes Sentry noise in the billing lifecycle cron which classifies 404 as expected but treats 500 as unexpected. Add correctLostStatus() helper that maps "Instance not " messages back to 404 when statusCodeFromError returned the default 500. Applied to both sanitizeError and sanitizeOpenclawConfigError.
Contributor
Code Review SummaryStatus: 1 Issues Found | Recommendation: Address before merge Overview
Issue Details (click to expand)CRITICALNone. WARNING
SUGGESTIONNone. Other Observations (not in diff)N/A Files Reviewed (2 files)
Fix these issues in Kilo Cloud Reviewed by gpt-5.4-20260305 · 313,570 tokens |
…ioned' match
The previous startsWith('Instance not ') check would remap real 409s from
requireGatewayControllerContext() to 404 when the status was lost across the
DO RPC boundary. Narrowed to an exact message match since 'Instance not
provisioned' is the only message thrown with status 404 in DO lifecycle code.
RSO
approved these changes
Apr 1, 2026
4 tasks
eshurakov
pushed a commit
that referenced
this pull request
Apr 1, 2026
jeanduplessis
added a commit
that referenced
this pull request
Apr 2, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Problem
KiloClaw platform routes return HTTP 500 for "Instance not provisioned" and "Instance not running" errors. The Durable Object throws with
{ status: 404 }, but custom error properties are lost crossing the Cloudflare DO RPC boundary.statusCodeFromError()defaults to 500. This causes recurring Sentry noise (KILOCODE-WEB-1P3P, KILOCODE-WEB-1GQT, KILOCODE-WEB-1GQS) because the billing lifecycle cron classifies 404/409 as expected but treats 500 as unexpected.Solution
correctLostStatus()helper inplatform.tsthat maps messages starting with"Instance not "back to 404 whenstatusCodeFromErrorreturned the default 500.sanitizeErrorandsanitizeOpenclawConfigErrorvia the shared helper..statussurvives RPC, no override for other safe prefixes like "Instance is not running", and generic error fallback.Why this approach
The fix is deliberately scoped to the platform route layer rather than changing the DO code,
withDORetry, orstatusCodeFromError. Those work correctly for errors that preserve.status— the problem is specifically the Cloudflare RPC boundary stripping custom properties. A message-based correction at the sanitization layer is the narrowest fix that avoids touching shared infrastructure.Related issues
Sentry issues: KILOCODE-WEB-1P3P, KILOCODE-WEB-1GQT, KILOCODE-WEB-1GQS
Verification
cd kiloclaw && pnpm test— 50 test files, 1156 tests passedpnpm typecheck— passed (0 errors in changed packages)pnpm format:check— passedpnpm lint— passedVisual Changes
N/A
Reviewer Notes
GatewayControllerError(409, 'Instance not provisioned')ingateway.ts:31was investigated — it runs inside the DO and is caught before crossing RPC, so its.statusis preserved. No fix needed there.status === 500(the default), so errors that already carry a valid.statusproperty are completely unaffected."Instance is not running"(different prefix from"Instance not ") is intentionally left at its current behavior — its producers mostly useGatewayControllerErrorwith explicit status codes.