-
-
Notifications
You must be signed in to change notification settings - Fork 283
Description
Summary
Prism currently sends structured output schemas to Gemini using the response_schema field (a proto-based API field). Gemini also exposes a newer response_json_schema field that accepts a richer subset of JSON Schema. Switching to response_json_schema fixes two real-world schema shapes that currently cause 400 INVALID_ARGUMENT errors with response_schema.
The two rejected fields
1. additionalProperties
When a schema contains additionalProperties: false on a nested object (e.g. inside items), Gemini returns:
Unknown name "additionalProperties" at 'generation_config.response_schema.properties[0].value.items': Cannot find field.
SchemaMap::toArray() already strips additionalProperties and name from the top-level array (line 28), but it can only recurse into properties/items when the schema is a native Prism ObjectSchema/ArraySchema. Custom schema implementations that implement HasSchemaType and serialize to a flat array via toArray() bypass the recursion, so nested additionalProperties passes through to the proto field and causes the 400.
2. Nullable union types ("type": ["string", "null"])
When a property is nullable, JSON Schema represents it as "type": ["string", "null"]. response_schema is a proto field that does not accept arrays for type, returning:
Unknown name "type" at '...': Proto field is not repeating, cannot start list.
Root cause
response_schema is a protobuf-mapped field with a strict subset of JSON Schema. response_json_schema is a newer field that accepts standard JSON Schema directly, without the proto restrictions.
Verification
Tested directly against the Gemini REST API with both field names using gemini-2.5-flash, gemini-2.5-flash-lite, and gemini-3.1-flash-lite-preview:
| Field | additionalProperties: false in nested object |
"type": ["string", "null"] |
|---|---|---|
response_schema |
❌ 400 INVALID_ARGUMENT | ❌ 400 INVALID_ARGUMENT |
response_json_schema |
✅ 200 | ✅ 200 |
response_json_schema works on all three models tested — it is not limited to Gemini 3.x.
Proposed fix
In Structured.php line 131, change:
'response_schema' => (new SchemaMap($request->schema()))->toArray(),to:
'response_json_schema' => (new SchemaMap($request->schema()))->toArray(),This is a one-line change. SchemaMap output is valid JSON Schema and passes through correctly under response_json_schema.
It may also be worth checking whether SchemaMap still needs to strip additionalProperties and name once response_json_schema is used, those fields are accepted by response_json_schema so the stripping in toArray() line 28 could potentially be relaxed, though keeping it is harmless.
References
- Gemini structured output docs: https://ai.google.dev/gemini-api/docs/structured-output
response_json_schemais documented under theGenerationConfigreference as the field for providing a JSON Schema directly