You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Permission prompts can silently lose tool-call context: DefaultOnError on rawInput #1979
ToolCallUpdate.raw_input is deserialized with serde_as(deserialize_as = "DefaultOnError") + serde(default) (agent-client-protocol-schema/src/v1/tool_call.rs:69-73), exported in the JSON schema as x-deserialize-default-on-error: true. Several sibling display fields (name, kind, status, title path) carry the same annotation. Meanwhile RequestPermissionRequest requires only sessionId/toolCall/options, and ToolCallUpdate requires only toolCallId.
Consequence for permission flows
If an agent sends a rawInput that fails to deserialize, the field silently becomes None. For a client rendering a permission prompt, "agent provided no input" and "agent provided input that didn't parse" are indistinguishable — a fully conformant request can render an argument-free approval prompt even though the agent believed it transmitted the arguments, and the human (or policy engine) approves with less context than was sent.
We hit this while evaluating ACP as the harness boundary for an agent-orchestration system where the permission request is the exact surface an approval binds to.
Not proposing erroring
The robustness intent is clear and good — a malformed metadata field shouldn't kill a session. The gap is only observability of the substitution.
Suggestions (either would resolve it)
Have the deserializing layer surface substitution, e.g. a reserved _meta marker or per-field flag, so clients can distinguish absent from unparseable and permission UIs can refuse or visibly flag defaulted context; or
A spec note in the permission-request docs that clients SHOULD apply heightened display treatment (or refusal) when rawInput is absent/defaulted on a permission-bearing tool call.
Verified against the v1.6.0 tag; apologies if the v2 draft already addresses this.
Drafted by an AI reviewer during an independent protocol evaluation; filed and endorsed by this account's owner.
I've been testing a small authorization layer around agent tool calls, and one thing I'm deliberately treating as part of the authorization decision is the exact normalized arguments — not just "the agent is allowed to use this tool."
Your example makes the distinction pretty important: approving the intent/tool while losing the actual arguments isn't really approving the action.
I'm curious whether you've considered binding the approval to a normalized/hashable representation of the exact tool + arguments, so any material change between approval and execution invalidates it.
I'm experimenting with that idea in AgentGuard and would be happy to share it if useful to you.
Hey — your ACP issue about rawInput potentially disappearing from permission prompts is really interesting.
I'm testing a small authorization layer where the exact normalized tool + arguments form part of the authorization decision, rather than treating "allowed to use this tool" as sufficient.
I'd love to pressure-test that idea against the problem you found.
Would you be interested in installing the tiny Python prototype and trying it on a real tool call? I'll help get it running for free — I'd mainly want to learn whether binding the decision to the exact call actually addresses something useful or whether I'm overengineering it.
Yeah, that distinction is really useful.
I think the “what was shown / what was approved or edited / what actually
executed” framing gets at something I’ve been thinking about with
AgentGuard too.
The last part is the one I’m most interested in. An approval record can be
perfectly accurate about what was reviewed and still not prove that the
same action ultimately reached the execution boundary.
That’s basically why I’ve been pushing the authorization check as close to
the actual side effect as possible, rather than treating the approval event
itself as the security boundary.
The point about execution_binding = "external" is especially interesting.
I’d rather have the model explicitly say “this record cannot prove that”
than quietly imply that it can.
Really appreciate you spelling that out. It’s a useful distinction to keep
in the architecture.
On Thu, 10 Sep 2026 at 9:59 am, g.okc ***@***.***> wrote:
*gustavo89587* left a comment
(agentclientprotocol/agent-client-protocol#1979)
<#1979 (comment)>
The interesting part here is not the deserialization failure itself, but
the authority transition that follows it.
If material tool-call context is lost during normalization, the approval
surface no longer represents the action that was originally proposed.
That creates a runtime invariant:
approval authority should not be granted from degraded action evidence
unless that degradation is explicit and policy-visible.
In other words:
provided input → parsing failure → silent absence
should not be equivalent to:
no input was provided.
The session can remain robust without making approval semantics lossy.
—
Reply to this email directly, view it on GitHub
<#1979?email_source=notifications&email_token=CLYKYAUQMLRWMAGHBBVLSZD5OHVGZA5CNFSNUABFM5UWIORPF5TWS5BNNB2WEL2JONZXKZKDN5WW2ZLOOQXTKNRRGA2DMNJVG422M4TFMFZW63VHMNXW23LFNZ2KKZLWMVXHJLDGN5XXIZLSL5RWY2LDNM#issuecomment-5610465575>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/CLYKYAXMBCU3LWLOZGWZ44L5OHVGZAVCNFSNUABGKJSXA33TNF2G64TZHMYTAMBXGI2TCMRZGY5US43TOVSTWNJRHA2TMMRQG4YDTILWAI>
.
You are receiving this because you commented.Message ID:
***@***.***
com>
Glad that distinction was useful. I think the execution boundary is exactly where this gets interesting.
An approval can prove what a human authorized, but unless the approved representation is bound to the operation that reaches the side effect, it still cannot prove what was executed.
I’ve been treating that uncertainty as first-class state rather than filling the gap with implied authority.
Your execution_binding = "external" framing makes that limitation explicit, which I think is the right direction.
A re-fetch could be a recovery mechanism, but I wouldn't make authorization depend on successful recovery alone.
The stronger invariant is:
if material action context was lost, approval authority remains incomplete until the reconstructed context is explicitly rebound to the operation being authorized.
So the flow could be:
parse failure → degraded evidence → no approval authority
Activity
Brodin2001 commentedon Aug 27, 2026
This is a really interesting failure mode.
I've been testing a small authorization layer around agent tool calls, and one thing I'm deliberately treating as part of the authorization decision is the exact normalized arguments — not just "the agent is allowed to use this tool."
Your example makes the distinction pretty important: approving the intent/tool while losing the actual arguments isn't really approving the action.
I'm curious whether you've considered binding the approval to a normalized/hashable representation of the exact tool + arguments, so any material change between approval and execution invalidates it.
I'm experimenting with that idea in AgentGuard and would be happy to share it if useful to you.
Brodin2001 commentedon Aug 27, 2026
Hey — your ACP issue about rawInput potentially disappearing from permission prompts is really interesting.
I'm testing a small authorization layer where the exact normalized tool + arguments form part of the authorization decision, rather than treating "allowed to use this tool" as sufficient.
I'd love to pressure-test that idea against the problem you found.
Would you be interested in installing the tiny Python prototype and trying it on a real tool call? I'll help get it running for free — I'd mainly want to learn whether binding the decision to the exact call actually addresses something useful or whether I'm overengineering it.
gustavo89587 commentedon Sep 9, 2026
The interesting part here is not the deserialization failure itself, but the authority transition that follows it.
If material tool-call context is lost during normalization, the approval surface no longer represents the action that was originally proposed.
That creates a runtime invariant:
approval authority should not be granted from degraded action evidence unless that degradation is explicit and policy-visible.
In other words:
provided input → parsing failure → silent absence
should not be equivalent to:
no input was provided.
The session can remain robust without making approval semantics lossy.
Brodin2001 commentedon Sep 10, 2026
gustavo89587 commentedon Sep 11, 2026
Glad that distinction was useful. I think the execution boundary is exactly where this gets interesting.
An approval can prove what a human authorized, but unless the approved representation is bound to the operation that reaches the side effect, it still cannot prove what was executed.
I’ve been treating that uncertainty as first-class state rather than filling the gap with implied authority.
Your execution_binding = "external" framing makes that limitation explicit, which I think is the right direction.
gustavo89587 commentedon Sep 23, 2026
A re-fetch could be a recovery mechanism, but I wouldn't make authorization depend on successful recovery alone.
The stronger invariant is:
if material action context was lost, approval authority remains incomplete until the reconstructed context is explicitly rebound to the operation being authorized.
So the flow could be:
parse failure → degraded evidence → no approval authoritythen, if recovery succeeds:
re-fetched context → normalized action → explicit approval → execution bindingThat avoids treating the re-fetch itself as proof that the recovered action is the same action originally proposed.
The important property is not just “show the context again,” but preserving continuity between proposed → displayed → approved → executed.