ARCPClient.dispatch(envelope:) only delivers tool.error envelopes when their correlation_id matches an entry in pendingByInvoke, at Sources/ARCP/Client/ARCPClient.swift:220. If the correlation id is missing or does not map to a pending invocation — for example a runtime error response correlated to a raw client.send invocation that bypassed invoke, an error delivered out of order after the invocation has already been resolved by a job terminal event, or an envelope whose correlation field was stripped by a relay — the dispatcher silently drops it. This is the same shape as the gap addressed for job.progress in issue #55 and leaves real error signals invisible to applications that drain client.unhandled, complicating diagnostics and hiding protocol violations from operators.
Fix prompt: Add an else branch to the .toolError case that yields the envelope to unhandledContinuation whenever there is no matching pending invocation, mirroring how jobCompleted, jobFailed, jobCancelled, and jobAccepted already fall back to unhandled. Add a dispatcher test that sends a tool.error envelope with no correlation_id and asserts it surfaces on client.unhandled, plus a regression test proving that a correlated tool.error still resolves the pending invocation with .failed and does not duplicate onto unhandled.
ARCPClient.dispatch(envelope:)only deliverstool.errorenvelopes when theircorrelation_idmatches an entry inpendingByInvoke, atSources/ARCP/Client/ARCPClient.swift:220. If the correlation id is missing or does not map to a pending invocation — for example a runtime error response correlated to a rawclient.sendinvocation that bypassedinvoke, an error delivered out of order after the invocation has already been resolved by a job terminal event, or an envelope whose correlation field was stripped by a relay — the dispatcher silently drops it. This is the same shape as the gap addressed forjob.progressin issue #55 and leaves real error signals invisible to applications that drainclient.unhandled, complicating diagnostics and hiding protocol violations from operators.Fix prompt: Add an
elsebranch to the.toolErrorcase that yields the envelope tounhandledContinuationwhenever there is no matching pending invocation, mirroring howjobCompleted,jobFailed,jobCancelled, andjobAcceptedalready fall back tounhandled. Add a dispatcher test that sends atool.errorenvelope with nocorrelation_idand asserts it surfaces onclient.unhandled, plus a regression test proving that a correlatedtool.errorstill resolves the pending invocation with.failedand does not duplicate ontounhandled.