Skip to content

fix(translator): do not treat a properties map as a schema node - #12931

Closed
killer30001000 wants to merge 5 commits into
diegosouzapw:release/v3.8.51from
killer30001000:fix/vertex-properties-schema-map
Closed

killer30001000 wants to merge 5 commits into
diegosouzapw:release/v3.8.51from
killer30001000:fix/vertex-properties-schema-map

Conversation

@killer30001000

Copy link
Copy Markdown
Contributor

Vertex AI rejects tool schemas when Phase 7 of cleanJSONSchemaForAntigravity() mistakes a properties map for a schema node and injects a synthetic type entry. A tool that legitimately declares a parameter named properties triggers this path, producing an invalid ninth parameters.properties value ("object").

Make injectObjectType() schema-map aware: descend into values of a properties map without processing the map itself as a schema node. Add a focused regression reproducing the Vertex failure and guard other keyword-named parameters.

Summary

  • Fix Gemini/Vertex tool-schema sanitization for tools that declare a legitimate parameter named properties.
  • Prevent Phase 7 (injectObjectType) from treating the properties map container itself as a schema node.
  • Preserve the existing object-type injection behavior for actual nested schemas.
  • No provider-specific hardcode, tool filter, or parameter rename is involved.

The failure reproduced as:

[400]: Invalid value at
'tools[0].function_declarations[43].parameters.properties[8].value'
(type.googleapis.com/google.cloud.aiplatform.v1.Schema), "object"

The synthetic ninth entry was created because the visitor recursively processed the property map itself. Since that map contained a user-defined key named properties, record.properties !== undefined incorrectly matched and caused type: "object" to be inserted into the map.

Related Issues

  • No dedicated issue.

Validation

  • Change type: other — Gemini/Vertex translator schema sanitization
  • Focused tests and relevant Gemini/Vertex schema regressions
  • npm run lint
  • Reconciled with the current active release base; focused checks rerun afterward
  • Production-code changes include a new automated test in this PR

Validation performed for the patch:

New regression + gemini-schema-recursive-type:
9 pass, 0 fail

Gemini/Vertex schema suite:
100 pass, 0 fail

Tool-calling regression suite:
16 pass, 0 fail

ESLint on both changed files:
0 errors

The branch was subsequently rebuilt directly on the current release/v3.8.51 tip. The resulting diff is one commit touching only the translator helper and the new regression test.

The same translator fix was also validated manually in a Docker build against the original Vertex request: the previously failing Combo/tool request succeeds.

Tests Added Or Updated

  • tests/unit/gemini-schema-properties-named-property.test.ts

The regression test verifies that:

  • a legitimate parameter named properties does not cause a synthetic type entry to be inserted into the surrounding property map;
  • the root schema remains type: "object";
  • the legitimate properties parameter remains an array with a valid object items schema;
  • existing additionalProperties sanitization continues to work;
  • other schema-keyword-like parameter names such as required, items, type, and description remain valid user-defined property names.

Coverage Notes

tests/unit/gemini-schema-properties-named-property.test.ts directly exercises the changed Phase 7 behavior in open-sse/translator/helpers/geminiHelper.ts and reproduces the schema shape responsible for the Vertex 400.

No existing assertions or schema sanitization behavior were weakened.

Reviewer Notes

The root cause is traversal context, not additionalProperties.

properties is a map from user-defined property names to subschemas. The fix therefore descends into the map's values without processing the map container itself as a schema node, matching the traversal pattern already used by removeUnsupportedKeywords().

There are no migrations, feature flags, API changes, provider-specific hardcodes, or tool-specific workarounds.

Vertex AI rejects tool schemas when Phase 7 of cleanJSONSchemaForAntigravity() mistakes a properties map for a schema node and injects a synthetic type entry. A tool that legitimately declares a parameter named `properties` triggers this path, producing an invalid ninth parameters.properties value (`"object"`).

Make injectObjectType() schema-map aware: descend into values of a `properties` map without processing the map itself as a schema node. Add a focused regression reproducing the Vertex failure and guard other keyword-named parameters.
@killer30001000
killer30001000 force-pushed the fix/vertex-properties-schema-map branch from 35a19f2 to 4b722c6 Compare September 11, 2026 20:10
@diegosouzapw

Copy link
Copy Markdown
Owner

Thanks for tracking this down against a real Vertex failure — the reproduction
and root-cause explanation are spot on. While triaging this alongside the rest
of the open Gemini-schema-sanitizer PRs, I found #13690 fixes the exact same
root cause in injectObjectType() but generalizes the guard into a shared
forEachSubschema() helper and applies it to 8 other visitor functions that
have the identical bug for other keyword-named properties (required, allOf,
enum, etc.) — including the delivery.pin.required case from #13477, which
your fix's injectObjectType-only scope doesn't actually reach.

Since we can't ship both diffs against the same lines, I'm recommending #13690
as the one we merge and this one closed as subsumed — with credit to you in
that PR/changelog for the independent Vertex repro. Thank you for the report.

Triage note: this is the review recommendation — the close itself happens only after the maintainer's per-PR sign-off (and, where a superseding PR is named, after it has landed). Nothing is being closed by this comment.

@killer30001000

Copy link
Copy Markdown
Contributor Author

Sounds great!

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants