-
Notifications
You must be signed in to change notification settings - Fork 111
Open
Description
Description
When using HasStructuredOutput agents with the OpenRouter provider, structured output requests fail
with:
OpenRouter Bad Request: output_format.schema: For 'object' type, property 'name' is not supported
The root cause is that Schema::toSchema() includes the name metadata field inside the JSON Schema
array, which is not a valid JSON Schema property for object type.
Root Cause
In src/Schema.php, the toSchema() method returns:
public function toSchema(): array
{
return [
'name' => $this->name,
...$this->schema->toArray(),
];
}
Prism's OpenRouter Structured handler (src/Providers/OpenRouter/Handlers/Structured.php) calls both
$request->schema()->name() and $request->schema()->toArray():
'response_format' => [
'type' => 'json_schema',
'json_schema' => [
'name' => $request->schema()->name(), // ✅ name at wrapper level
'strict' => true,
'schema' => $request->schema()->toArray(), // ❌ also contains 'name'
],
],
This results in name appearing twice in the payload — once correctly at the json_schema level (added
by Prism), and once incorrectly inside the schema object (from Laravel AI SDK's toSchema()):
{
"response_format": {
"type": "json_schema",
"json_schema": {
"name": "schema_definition",
"strict": true,
"schema": {
"name": "schema_definition",
"type": "object",
"properties": { "..." },
"required": ["..."]
}
}
}
}
OpenRouter rejects this because name is not a valid property for a JSON Schema of type object.
Suggested Fix
Remove name from toSchema() / toArray() — these methods should return a pure JSON Schema without
metadata:
public function toSchema(): array
{
return $this->schema->toArray();
}
The name is already accessible via the dedicated name() method, which Prism correctly calls
separately.
Related
This is architecturally similar to #139 (Gemini fails with additionalProperties leaking through the
same serialization path).
Reproduction
Any agent using HasStructuredOutput targeting OpenRouter:
class StrategyAgent implements Agent, HasStructuredOutput
{
use Promptable;
public function schema(JsonSchema $schema): array
{
return [
'queries' => $schema->array()
->items($schema->string())
->description('A list of search queries.'),
];
}
}
// Trigger:
$agent->prompt(prompt: 'Generate queries.', model: 'anthropic/claude-sonnet-4.5');
Versions
- laravel/ai: v0.1.5
- prism-php/prism: v0.99.19
- PHP: 8.4
- Provider: OpenRouterReactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels