Skip to content

Conversation

@wrenj
Copy link
Collaborator

@wrenj wrenj commented Feb 12, 2026

To cover common errors not covered by the json schema

Copy link
Contributor

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

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 introduces a new validation layer for A2UI JSON payloads, which is a great addition to ensure data integrity beyond basic schema validation. The new validation.py module is well-structured and includes checks for component integrity, topology (cycles, orphans), recursion depth, and path syntax. The accompanying test suite in test_validation.py is comprehensive and covers many important edge cases.

My feedback includes a critical point about silent error handling that could lead to validation being skipped, and a suggestion to improve maintainability by refactoring hardcoded values into constants. Overall, this is a solid contribution that significantly improves the robustness of A2UI message processing.

Comment on lines +189 to +191
except Exception:
# If schema traversal fails, return empty map
pass
Copy link
Contributor

Choose a reason for hiding this comment

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

high

Using a broad except Exception: with a pass is dangerous. It will silently swallow any errors that occur during schema parsing (e.g., due to an unexpected schema structure), resulting in an empty ref_map. This effectively disables all component reference validation without any warning, which could allow invalid JSON to pass through. At a minimum, this should log a warning to indicate that reference validation was skipped. A better approach would be to handle more specific exceptions related to key/index errors during dictionary traversal.

Comment on lines +230 to +250
if global_depth > 50:
raise ValueError("Global recursion limit exceeded: Depth > 50")

if isinstance(item, list):
for x in item:
traverse(x, global_depth + 1, func_depth)
return

if isinstance(item, dict):
# Check for path
if PATH in item and isinstance(item[PATH], str):
path = item[PATH]
if not re.fullmatch(JSON_POINTER_PATTERN, path):
raise ValueError(f"Invalid JSON Pointer syntax: '{path}'")

# Check for FunctionCall
is_func = CALL in item and ARGS in item

if is_func:
if func_depth >= 5:
raise ValueError(f"Recursion limit exceeded: {FUNCTION_CALL} depth > 5")
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The recursion depth limits (50 for global, 5 for function calls) are hardcoded as magic numbers. To improve readability and maintainability, it's better to define these as module-level constants (e.g., MAX_GLOBAL_DEPTH = 50, MAX_FUNC_CALL_DEPTH = 5). This makes their purpose clear and allows them to be easily located and modified in one place.

1. **JSON Schema Validation**: Ensures payload adheres to the A2UI schema.
2. **Component Integrity**:
- All component IDs are unique.
- A 'root' component exists.
Copy link
Collaborator

Choose a reason for hiding this comment

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

If the updateComponents message only include a partial list of components to update an existing surface, does it also require a root component?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Should we only enforce the root requirement if there is a CreateSurface message along with the UpdateComponents message?


a2ui_schema = await self.get_a2ui_schema(tool_context)
jsonschema.validate(instance=a2ui_json_payload, schema=a2ui_schema)
validate_a2ui_json(a2ui_json_payload, a2ui_schema)
Copy link
Collaborator

Choose a reason for hiding this comment

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

What is the expected format of the a2ui_schema?

v0.9 is a modularized version with multiple schemas. Do we need to bundle them into a unified one?

#557 adds an A2uiValidator that builds referencing registry to work with multiple schemas: https://github.com/nan-yu/A2UI/blob/836b2858833516ec532fdaa5366e0c4f386c72ad/a2a_agents/python/a2ui_agent/src/a2ui/inference/schema/validator.py. I think we can move these additional validations into the A2uiValidator.

The send_a2ui_to_client_toolset.py will extract the A2uiCatalog instance stored in the session and invoke the validator to validate the json payload, for example, f350823#diff-5f858e097e91850cde41d939245f10a3ef616ec3875236afcb4cfa4105f4384aR279.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Todo

Development

Successfully merging this pull request may close these issues.

2 participants