fix(server): a provider's internal error reports what actually failed - #16
Merged
Merged
Conversation
An ACP agent answers any unclassified handler throw with the standard -32603 "Internal error" and puts the thrown error's own message in `data`. T3 reported `message` alone, so a failed turn read "Internal error" followed by the decoder's JavaScript stack — nothing an operator can act on, and the one useful sentence was already on the wire. The ACP error mapper now folds that payload into the reported detail (`data.details`, a plain string payload, or compact JSON), deduped against the message and capped so a runaway payload cannot land whole in the timeline. All three ACP adapters share the mapper, and the failure activity already prefers this detail over a pretty-printed cause. Built with Claude Opus 5 on Oh My Pi.
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.
Problem
A failed omp turn reported this, and nothing else:
-32603 "Internal error"is what an ACP agent answers for any unclassified handler throw, with the thrown error's own message tucked intodata:AcpRequestErrorkeeps that payload, butmessagereturnserrorMessagealone andmapAcpToAdapterErrorreported exactly that. The one useful sentence was on the wire and never made it to the user — and it is not recoverable elsewhere either: the native ACP logs record shapes only (summarizePayload), and the child's stderr is drained.Fix
The ACP error mapper folds the payload into the reported detail —
data.details, a plain string payload, or compact JSON — deduped when the message already contains it, and capped at 600 chars so a runaway payload cannot land whole in the timeline. All three ACP adapters share this mapper, andformatFailureDetailalready prefers this detail over a pretty-printed cause.Verification
acp-mock-agent.tsgainsT3_ACP_PROMPT_ERROR_DETAILS, so a test reproduces the exact wire shape (-32603+data.details).OmpAdaptertest asserts the sentence reachesturn.completed.errorMessage— fails onmain-xavierwith the assertion above.AcpAdapterSupport+OmpAdapter+GrokAdapter+CursorAdapter: 76 tests green. tsgo clean; lint/format clean.Known gap, not addressed here: if a provider crashes instead of answering, its stderr is still discarded (
packages/effect-acp/src/_internal/stdio.tsdrains it), so we get only a process-exit error. omp writes its own log file, which is why I left the transport alone.Built with Claude Opus 5 on Oh My Pi.