Repository navigation
fix: name the field or reason in four failed tool results (#2149) - #2150
Merged
Merged
Conversation
…ceanbase#2149) The PreToolUse hook mapped every 401/403 from the Scope binding lookup to the generic "could not resolve the current Scope binding" reason, so agents told the user the binding was broken instead of naming the rejected credential. Classify the denials the same way session_binding.py does, keep transport and unresolved-binding failures on the existing reason, and catch protocol-level http.client errors so the hook denies instead of crashing. Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
…anbase#2149) Four failed tool results left agents to guess what to change. Dream evidence selection now reports the rejected field and both bounds, separating an empty selection from too many Artifacts and from the combined reference limit. Candidate validation maps the internal artifacts field to the public artifact_refs field with a stable reason instead of returning no details. Working-note expiry names expires_at and distinguishes a missing time zone from a past expiry. Status codes and error codes are unchanged. Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
guamiao
requested review from
Alanxtl,
AlexStocks,
PsiACE and
frostming
as code owners
October 21, 2026 07:27
hidb4ai
reviewed
Oct 21, 2026
hidb4ai
left a comment
Contributor
There was a problem hiding this comment.
One non-blocking P3 issue in the evidence-limit diagnostic.
…ase#2150) revise_tags has a combined 32-reference limit and no separate 20-Artifact limit, so its rejection message must not tell the agent to discard valid Artifact evidence. Keep the operation-specific bounds in the field error and cover both the rejecting and the accepted boundary. Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
…ase#2150) Exercise the operation-specific rejection and accepted boundary through the public route, and assert the exact response details instead of a status check that also passes on a missing Scope. Unify the lower-bound wording with the combined reference limit. Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
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.
Closes #2149.
Rationale for this change
The agent tool recovery evaluation (#2067 / #2146) found four failed PowerContext tool results that did not tell the agent what to change: three Server 422 responses omitted the rejected field, and the Codex plugin reported an authorization denial as a Scope-binding failure. Agents guessed, retried with changed arguments, or told the user the wrong cause.
What changes are included in this PR?
create_dream_run): an emptyartifactsselection reportsloc=["artifacts"]with typeevidence_selection_required; more than 20 Artifacts reportsartifactswithevidence_limit_exceeded; more than 32 references counting Sources reportssourceswithevidence_limit_exceeded. Messages state the bounds for the selected operation:revise_tagshas a combined limit of 32 references and no separate 20-Artifact limit.propose_experience):InvalidCandidateErrordetails map the internalartifactsfield to the publicartifact_refsfield with a stable reason (target_not_in_artifact_refs), and nametargetfor family/target failures. Internal-only fields and reasons shared by several public fields keepdetails: null; no exception text is echoed.capture_working_note): a past expiry returns{"field": "expires_at", "reason": "not_in_future"}, and the runtime separatesworking-note-expiry-timezonefromworking-note-expiry-past. Replay of an existing note is unchanged.http.clienterrors so the hook denies instead of crashing.revise_tagsboundary), and direct runtime tests for both expiry reasons.Status codes and outer error codes are unchanged. No OpenAPI or generated model changes were required (
scripts/generate_api.py --checkpasses).Are there any user-facing changes?
Error
detailsnow carry a field name and a stable reason so an agent can correct the request. No endpoints or request fields change. Known limits:evidence,basis,audit,family) and the approve-only lineagesourceserror keepdetails: null.expires_atis rejected by the transport model astimezone_aware; thefield/reasonshape applies to the past-expiry path and to direct runtime calls.revise_tags: the runtime appendstag_target.basis_refto the resolved Artifacts, so a 32-reference selection is only valid end to end when that basis Artifact is already part of the selection. This PR only corrects the admission message; the counting mismatch should be handled separately.How was this change tested?
pytest tests/builtin/dream tests/builtin/review tests/e2e/test_builtin_runtime.py tests/e2e/test_runtime_server.py tests/e2e/test_artifact_dreaming.py tests/e2e/test_candidate_review.py tests/test_api_contract.py tests/test_error_details.py tests/e2e/test_request_error_details.py -q→ 194 passed, 82 skipped (before the review follow-up).pytest tests/builtin/dream tests/e2e/test_request_error_details.py -q→ 11 passed (after the review follow-up).pytest tests/codex_plugin/test_scope_binding.py -q→ 84 passed.ruff check,ruff format --check, andty checkon the changed files pass.python scripts/generate_api.py --checkpasses.tests/builtin/runtime/test_extraction_diagnostics.py::test_extraction_diagnostics_observes_spawned_worker_failure_and_stopped_supervisor[_worker_crash-...]also fails on a cleanupstream/mastercheckout.AI usage statement
AI-assisted: Claude Code (Anthropic, Claude Sonnet 4.6) was used to implement the change and write the tests. The resulting diff was reviewed by two independent agent reviewers, and the reviewer P3 finding was addressed in commits
3835fbdaand641469f8.