Skip to content

Resolve inconsistency around catalogId. - #3650

Merged
polina-c merged 4 commits into
mainfrom
conflict
Oct 27, 2026
Merged

polina-c merged 4 commits into
mainfrom
conflict

Conversation

@polina-c

@polina-c polina-c commented Oct 27, 2026 •

Copy link
Copy Markdown
Collaborator

Fixes #3596
Fixes #3555
Fixes #3530

Description

The v1.0 spec gave two answers for a callRendererFunction whose callFunction has no catalogId. The JSON schema requires the field, so the message is malformed. The protocol doc said the renderer answers it with INVALID_FUNCTION_CALL. This PR goes with the schema: a missing catalogId is a malformed message, the same as a missing functionCallId.

INVALID_FUNCTION_CALL would mean the renderer reports the error back to the agent. But the message does not follow the schema, and an agent can check this before it sends the message. Agents should validate their messages on the server side, so that a renderer never sees one like this.

All four cores (web_core, Python, Swift and Dart) already throw A2uiValidationError for this message, so no core code changes.

Changes

  1. a2ui_protocol.md: the catalogId property no longer says that an omitted catalogId gets INVALID_FUNCTION_CALL. It says the message is malformed and that agents should validate outgoing messages against the schema. A catalogId that names an unregistered catalog still gets INVALID_FUNCTION_CALL.
  2. a2ui_core.blueprint.md: the RpcHandler catalog resolution no longer falls back to the surface's defaultCatalog when a call names no catalog. None of the RpcHandler implementations had this fallback. A new paragraph says that parsing rejects such a message before the handler sees it, and that no rendererFunctionResponse is sent.
  3. rpc_functions.yaml: new conformance case test_rpc_call_renderer_function_invalid_payload_missing_catalog_id. It calls a function that a loaded catalog defines, without catalogId, and expects a validation error that mentions catalogId. Before this, no conformance case covered an omitted catalogId.
  4. RPCConformanceTests.swift: the Swift conformance runner decoded messages with a plain JSONDecoder, which accepts a missing catalogId. It also did not fail when an expected error never came, so the new case would have passed without being checked. The runner now parses with AgentToRendererMessage.parseAll, which runs the version adapter's checks, the same ones the message processor runs. It fails when a message the case expects to be rejected parses, and when a message the case expects to parse is rejected.

Testing

The RPC conformance tests pass in Swift, Python and Dart. To confirm that each runner checks the new case, I temporarily changed its expected message to a string that does not occur, and all three failed.

web_core does not run this conformance suite. Its message-processor.test.ts already asserts the throw.

Related

With this decision, #3555 (changes web_core to answer with INVALID_FUNCTION_CALL) and #3530 (tracks the Swift throw as a bug) can be closed.

🤖 Agent-generated

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates the A2UI protocol specification, blueprint, and conformance tests to ensure that a callRendererFunction message missing a catalogId is rejected as a schema validation error rather than being handled as an invalid function call. In the Swift conformance tests, AgentToRendererMessage.parseAll is now used to enforce these schema checks. The review feedback suggests improving the Swift test assertions by safely unwrapping the expected error and guarding the inbound call execution to prevent redundant or misleading assertions if validation unexpectedly succeeds.

Comment thread swift/core/Tests/A2UIConformanceTests/RPCConformanceTests.swift
Comment thread blueprints/modules/a2ui_core.blueprint.md Outdated
Comment thread blueprints/modules/a2ui_core.blueprint.md Outdated
Comment thread conformance/core/rpc_functions.yaml Outdated
Comment thread specification/v1_0/docs/a2ui_protocol.md Outdated
@polina-c
polina-c enabled auto-merge (squash) October 27, 2026 17:06
@polina-c
polina-c merged commit ab3954f into main Oct 27, 2026
47 checks passed
@polina-c
polina-c deleted the conflict branch October 27, 2026 17:26
@github-project-automation github-project-automation Bot moved this from Todo to Done in A2UI Oct 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants