docs: protocol spec v0.1.25.8 — UNIT_MISMATCH + BUDGET_NOT_FOUND#411
Merged
docs: protocol spec v0.1.25.8 — UNIT_MISMATCH + BUDGET_NOT_FOUND#411
Conversation
…_NOT_FOUND) Updates docs to reflect three recent cycles-protocol-v0.yaml changes: 1. UNIT_MISMATCH (400) broadened from 2 to 4 operations Previously documented for commit + event. Spec normative text now covers reserve and decide as well — both can return 400 UNIT_MISMATCH when estimate.unit doesn't match any budget at the derived scopes but at least one of those scopes has a budget in a different unit. 2. BUDGET_NOT_FOUND (404) as a distinct error code POST /v1/reservations and POST /v1/events now explicitly return 404 BUDGET_NOT_FOUND (distinct from NOT_FOUND for missing reservations) when no budget exists at any derived scope in any unit. Previously docs conflated both 404 cases under NOT_FOUND. 3. /v1/decide with missing budget returns 200 DENY, not 404 Consistent with decide's policy of surfacing budget-state conditions as decisions. Reason code is BUDGET_NOT_FOUND. UNIT_MISMATCH is still returned as 400 because it's a request-validity error, not a budget-state condition. Also documents the details.expected_units field (array of units for which a budget does exist at the scope) so clients can self-correct without a separate lookup. Files updated: - protocol/api-reference-for-the-cycles-protocol.md — reserve, decide, events error tables - protocol/error-codes-and-error-handling-in-cycles.md — split NOT_FOUND section, new BUDGET_NOT_FOUND section, broadened UNIT_MISMATCH section, updated error count 15 -> 16 - protocol/understanding-units-in-cycles-*.md — broadened UNIT_MISMATCH description to cover all four operations, added BUDGET_NOT_FOUND note - how-to/budget-allocation-and-management-in-cycles.md — scope lookup table and reservation rejection code - how-to/troubleshooting-and-faq.md — updated "first reservation" symptom to use BUDGET_NOT_FOUND - how-to/error-handling-patterns-in-python.md — retryable table - how-to/error-handling-patterns-in-cycles-client-code.md — retryable table Spec reference: cycles-protocol-v0.yaml commits 577daf2 (add decide to UNIT_MISMATCH list), beb00c1 (document 404 on /v1/reservations + /v1/events), edb6b13 (broaden UNIT_MISMATCH to reserve path).
…onCode enum Follow-up to previous commit on this branch (ac2fbcb). Two follow-up commits to cycles-protocol-v0.yaml corrected spec text that I had faithfully transcribed but which was itself wrong: 1. runcycles/cycles-protocol ca1f672 — the runtime plane's ErrorCode enum only contains NOT_FOUND (not BUDGET_NOT_FOUND). The reference server returns `{"error": "NOT_FOUND", "message": "Budget not found for provided scope: ..."}` for the "no budget at any scope" case on non-dry reserve and /v1/events. BUDGET_NOT_FOUND never appears in the `error` field of 4xx runtime-plane responses. 2. runcycles/cycles-protocol ee88137 — the `reason_code` field on DecisionResponse and ReservationCreateResponse (dry_run only) is now a closed enum (DecisionReasonCode) with six values: BUDGET_EXCEEDED, BUDGET_FROZEN, BUDGET_CLOSED, BUDGET_NOT_FOUND, OVERDRAFT_LIMIT_EXCEEDED, DEBT_OUTSTANDING. BUDGET_NOT_FOUND IS a valid value here — on 200 DENY responses only, never on 4xx. Changes: - Reverted all `BUDGET_NOT_FOUND (404)` wire-code references to `NOT_FOUND (404)` with the message `"Budget not found for provided scope: ..."` carrying the specific reason. - Merged the two 404 sections in protocol/error-codes-and-error- handling-in-cycles.md back into a single NOT_FOUND (404) section with two contexts (missing reservation, missing budget), matching the runtime plane's single-wire-code design. - Added a new "Decision reason codes" section to protocol/error- codes-and-error-handling-in-cycles.md documenting the full DecisionReasonCode enum (6 values) with per-value semantics and the "forward compatibility" note from the spec. - Updated protocol/api-reference-for-the-cycles-protocol.md /v1/decide section to document the reason_code enum inline in the Response (200 OK) description. - Reverted error count in the Summary from 16 → 15 (BUDGET_NOT_FOUND is not a wire error code). - Updated troubleshooting-and-faq.md heading back to "NOT_FOUND on first reservation" and added explanation of how the message field distinguishes missing-reservation from missing-budget. - Updated error-handling-patterns docs (Python + client-code) to collapse the BUDGET_NOT_FOUND row back into NOT_FOUND, with the message-based distinction explained in the Meaning column. - Broadened understanding-units doc to mention that /decide and dry-run surface the same condition as 200 DENY reason_code= BUDGET_NOT_FOUND. Spec reference: cycles-protocol-v0.yaml commits ca1f672, ee88137 (both merged via runcycles/cycles-protocol#26).
…cide/dry-run pages Follow-up verification pass against spec v0.1.25.8. Three fixes: 1. api-reference dry-run note was inaccurate. Said "4xx error codes above only apply when dry_run is false or omitted" — but request- validity errors (INVALID_REQUEST, UNIT_MISMATCH, UNAUTHORIZED, FORBIDDEN, IDEMPOTENCY_MISMATCH) still return 4xx on dry-run. Only budget-state conditions flip to 200 DENY. Narrowed the claim to the 5 budget-state reason codes + the 404 "no budget" case. 2. how-decide-works-in-cycles page listed `reason_code` as a response field but didn't enumerate values. Added an inline 6-row table for the DecisionReasonCode enum (BUDGET_EXCEEDED, BUDGET_FROZEN, BUDGET_CLOSED, BUDGET_NOT_FOUND, OVERDRAFT_LIMIT_EXCEEDED, DEBT_OUTSTANDING) with the cross-reference to the error-codes-and-error-handling page for full semantics. 3. dry-run-shadow-mode-evaluation page similarly had a "reason_code on DENY" section that didn't list values. Added the same enum reference + the note that dry-run `BUDGET_NOT_FOUND` corresponds to the same underlying condition non-dry reserve surfaces as HTTP 404 with error=NOT_FOUND.
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
Aligns docs with three recent
cycles-protocol-v0.yamlchanges to the runtime error contract:UNIT_MISMATCH (400)broadened from 2 → 4 operations. Previously documented only for commit + event; now also applies to reserve and decide whenestimate.unitdoes not match any budget at the derived scopes but at least one of those scopes has a budget in a different unit.BUDGET_NOT_FOUND (404)added as a distinct error code onPOST /v1/reservationsandPOST /v1/events— docs previously conflated this with the genericNOT_FOUNDused for missing reservations./v1/decidewith missing budget returns200 DENY reason_code=BUDGET_NOT_FOUND, not a 404 — consistent with decide's policy of surfacing budget-state conditions as decisions.UNIT_MISMATCHis still returned as 400 because it's a request-validity error.details.expected_unitsfield onUNIT_MISMATCHerrors so clients can self-correct without a separate lookup.Files changed
protocol/api-reference-for-the-cycles-protocol.md— reserve, decide, events error tablesprotocol/error-codes-and-error-handling-in-cycles.md— splitNOT_FOUND/BUDGET_NOT_FOUNDsections, broadenedUNIT_MISMATCHsection, error count 15 → 16protocol/understanding-units-in-cycles-usd-microcents-tokens-credits-and-risk-points.md— UNIT_MISMATCH descriptionhow-to/budget-allocation-and-management-in-cycles.md— scope-lookup bullet + tablehow-to/troubleshooting-and-faq.md— "first reservation" symptom headinghow-to/error-handling-patterns-in-python.md— retryable tablehow-to/error-handling-patterns-in-cycles-client-code.md— retryable tableSpec references
Upstream commits on
runcycles/cycles-protocol:577daf2— add (d) decide to the normative UNIT_MISMATCH case listbeb00c1— document 404 on/v1/reservations+/v1/events, rename details fieldavailable_units→expected_unitsedb6b13— broaden UNIT_MISMATCH normative description to cover reserve pathTest plan
npm run build— VitePress build completes without link errorsnpm run dev— spot-check the 4 most-changed pages render correctly (error-codes-and-error-handling, api-reference, troubleshooting-and-faq, understanding-units)NOT_FOUND (404)language remains in reserve/event error tables