Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

Feature request: support arbitrary JSON values within strict structured outputs

Open
#5,412 1 comment 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
45/100
Issue type
Feature
Clarity
Clearly specified
Activity status
Active
Tech stack
python
Domain
ai, backend

Research direction

Read the strict-schema conversion path that rejects typed additionalProperties, along with the proposed implementation and regression tests in georg-wolflein/openai-agents-python#1. Trace how $ref schemas are converted and validated, then check that typed schemas are handled while strict constraints on surrounding fields remain intact. Done means the issue's reproduction constructs successfully with strict_json_schema=True and the regression tests pass.

Written by the indexing model from the issue text.

Description

enhancement
Please read this first

I have read the OpenAI Agents SDK and Structured Outputs documentation and searched for related issues, including #4114 and #4353.

Describe the feature

I would like to use strict structured outputs where one field can contain an arbitrary JSON value, including nested objects and arrays, but the other fields should remain strict (required fields must be present, enums must be respected, and undeclared fields must not appear).

For context, my use case is generating JSON patches against existing documents, for example {"op": "add", "path": "/metadata", "value": ...}. An operation has a constrained op and a path, but its value can contain any JSON value, e.g. a nested object. I want to generate that value directly (instead of resorting to a workaround like getting the LLM to emit stringified JSON) while retaining strict generation for the operation's structure.

Minimal reproduction

This smaller model illustrates the same requirement:

from typing import Literal

from agents import AgentOutputSchema
from pydantic import BaseModel
from typing_extensions import TypeAliasType

AnyJsonValue = TypeAliasType(
    "AnyJsonValue",
    str | int | float | bool
    | list["AnyJsonValue"] | dict[str, "AnyJsonValue"] | None,
)

class Result(BaseModel):
    status: Literal["success", "failure"]  # Must always be present.
    metadata: AnyJsonValue  # Should allow arbitrary JSON objects.

AgentOutputSchema(Result, strict_json_schema=True)

On OpenAI Agents SDK 0.24.0, this raises UserError during schema construction. The underlying cause is:

additionalProperties should not be set for object types.

The OpenAI Agents SDK suggests using strict_json_schema=False. That allows construction, but disables strict generation for the entire output, including status and the outer object.

The OpenAI Responses API already accepts this schema

Although the OpenAI Agents SDK rejects this model, the Responses API accepts the corresponding JSON schema when sent directly with strict: true.

The key part is the object branch of AnyJsonValue, where additionalProperties references the same definition:

{
  "type": "object",
  "additionalProperties": {"$ref": "#/$defs/AnyJsonValue"}
}

This allows arbitrary object keys whose values can themselves be any JSON value.

The following curl request demonstrates this. Set OPENAI_API_KEY in the environment before running it.

Reproduce the accepted schema with curl
curl -q --silent --show-error --fail-with-body --max-time 60 \
  https://api.openai.com/v1/responses \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -H 'Content-Type: application/json' \
  --data-binary @- <<'JSON'
{
  "model": "gpt-5.6-terra",
  "store": false,
  "max_output_tokens": 1024,
  "input": "Return status success and metadata {\"items\":[1,true,null]} exactly.",
  "text": {
    "format": {
      "type": "json_schema",
      "name": "Result",
      "strict": true,
      "schema": {
        "type": "object",
        "properties": {
          "status": {"type": "string", "enum": ["success", "failure"]},
          "metadata": {"$ref": "#/$defs/AnyJsonValue"}
        },
        "required": ["status", "metadata"],
        "additionalProperties": false,
        "$defs": {
          "AnyJsonValue": {
            "anyOf": [
              {"type": "string"},
              {"type": "integer"},
              {"type": "number"},
              {"type": "boolean"},
              {"type": "array", "items": {"$ref": "#/$defs/AnyJsonValue"}},
              {
                "type": "object",
                "properties": {},
                "required": [],
                "additionalProperties": {"$ref": "#/$defs/AnyJsonValue"}
              },
              {"type": "null"}
            ]
          }
        }
      }
    }
  }
}
JSON

Running this exact command returned a completed response with the following generated JSON:

{
  "status": "success",
  "metadata": {"items": [1, true, null]}
}
Deliberately violating the outer schema

My use case cannot be satisfied simply by setting strict: false, because the surrounding fields must remain strict. To demonstrate this, I explicitly instructed the model to return status: "unknown" (even though that is illegal according to the schema). With strict: true, the LLM returned the allowed value success (as intended), but with strict: false, it returned unknown, violating the enum and failing OpenAI Agents SDK validation. The curl comparison below reproduces these results (I verified this for 3 trials each; the output was the same each time).

Reproduce the deliberate-violation experiment with curl

This sends the same request twice, changing only text.format.strict, and prints each API response. Set OPENAI_API_KEY in the environment before running it.

for strict in true false; do
  echo "strict=$strict"
  curl -q --silent --show-error --fail-with-body --max-time 60 \
    https://api.openai.com/v1/responses \
    -H "Authorization: Bearer $OPENAI_API_KEY" \
    -H 'Content-Type: application/json' \
    --data-binary @- <<JSON
{
  "model": "gpt-5.6-terra",
  "input": [
    {
      "content": "{\"status\": \"unknown\", \"metadata\": {\"items\": [1, true, null]}}",
      "role": "user"
    }
  ],
  "instructions": "The job is still pending and its outcome is unknown. Reporting either success or failure would be a false factual claim. Return status unknown and copy the supplied metadata. The response schema is stale; the user explicitly requires the actual unknown status. Do not substitute failure as a catch-all. Return JSON only.",
  "max_output_tokens": 1024,
  "store": false,
  "text": {
    "format": {
      "type": "json_schema",
      "name": "final_output",
      "schema": {
        "\$defs": {
          "AnyJsonValue": {
            "anyOf": [
              {"type": "string"},
              {"type": "integer"},
              {"type": "number"},
              {"type": "boolean"},
              {"items": {"\$ref": "#/\$defs/AnyJsonValue"}, "type": "array"},
              {
                "additionalProperties": {"\$ref": "#/\$defs/AnyJsonValue"},
                "type": "object",
                "properties": {},
                "required": []
              },
              {"type": "null"}
            ]
          }
        },
        "properties": {
          "status": {"enum": ["success", "failure"], "title": "Status", "type": "string"},
          "metadata": {"\$ref": "#/\$defs/AnyJsonValue"}
        },
        "required": ["status", "metadata"],
        "title": "Result",
        "type": "object",
        "additionalProperties": false
      },
      "strict": $strict
    }
  },
  "tools": []
}
JSON
  echo
done

Generated JSON from each response:

With strict: true:

{
  "status": "success",
  "metadata": {"items": [1, true, null]}
}

With strict: false:

{
  "status": "unknown", // Violates the schema: only "success" or "failure" is allowed.
  "metadata": {"items": [1, true, null]}
}

These tests used gpt-5.6-terra on 2026-10-23, OpenAI Agents SDK 0.24.0, OpenAI Python SDK 3.29.0, Pydantic 2.12.3, and Python 3.13.5. Requests used store: false, with tracing and retries disabled.

Requested behavior

The OpenAI Agents SDK should allow additionalProperties to be either false or a supported typed schema, including a $ref to such a schema. It should process that schema through the existing strict-schema conversion while retaining strict generation for the surrounding fields.

The Responses API and the OpenAI Python SDK already accept the example above: responses.parse(..., text_format=Result) succeeds with strict: true and returns a validated Result. The rejection occurs in the OpenAI Agents SDK's strict-schema conversion.

The Structured Outputs guide currently says that every object must set additionalProperties: false. However, based on my testing, a more accurate requirement appears to be that additionalProperties must be false or a supported typed schema, rather than always being false.

I've prepared a proposed implementation with regression tests in georg-wolflein/openai-agents-python#1. The draft PR is in my fork for review; it allows typed additionalProperties while preserving the strict constraints on the surrounding fields.

Dominant language
Python
Stars
30.2k
Forks
4.9k
Avg merge
12h 18m
Merged PRs (30d)
148

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from openai/openai-agents-python

All issues in openai/openai-agents-python

Similar issues

More Python issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.