Skip to content

Sessions quietly finish with no answer when answer_format has an enum inside a list of objects, and no error is raised #197

Open

Description

@arthurkatcher

Platform behavior rather than an SDK bug, but this repo seems to be the closest public tracker (same spirit as #194).

Summary

Found while building an agent on the Computer Use Agents platform — a QA reviewer whose report is a structured list of graded findings, which turns out to be exactly the schema shape that triggers this.

Sessions with an answer_format schema containing an enum field inside an object in an array — e.g. missions: [{outcome: "achieved" | "friction" | "blocked"}] — finish completed with latest_answer: null. No error, no answer_validation, nothing in the events; the failure is completely silent. Replace that one enum with a plain string and the same session returns a valid structured answer. Flat top-level enums are fine; it has to be nested in an array item, and the model has to actually emit an entry (empty arrays slip through, which makes it look intermittent).

Calling the Models API directly with the same schema shows where the answers go. With chat_template_kwargs: {"enable_thinking": true} (how agent sessions run), response_format: json_schema outputs come back corrupted at high rates — <loc_*> grounding tokens and serving artifacts leak inside string values, answers fill with tab runs, generations run away to finish_reason: length. With thinking off, the same requests are clean every time.

This looks like two problems stacked:

  1. Model serving: schema-constrained generation is unstable when the reasoning template is enabled.
  2. Agents platform: a final answer that fails schema validation is discarded silently — the session still ends completed with latest_answer: null and error_code: null, although the docs define answer_validation for exactly this case. This turns a model-side bug into an invisible one: we spent three multi-agent QA runs debugging our orchestration before finding it.

Reproduction 1 — agents platform (deterministic)

Two sessions, EU region, hai-agents 1.0.7, identical except one field type:

from hai_agents import Client

FAILS = {  # enum inside array item -> latest_answer is null
    "type": "object",
    "properties": {
        "answer": {"type": "string"},
        "items": {"type": "array", "items": {
            "type": "object",
            "properties": {"outcome": {"type": "string", "enum": ["achieved", "friction", "blocked"]}},
            "required": ["outcome"]}}},
    "required": ["answer", "items"]}

# PASSES: same schema with {"type": "string"} instead of the enum member.

client = Client()
r = client.run_session(
    agent={"name": "repro", "description": "answer_format repro",
           "environments": ["h/textual_browser"], "model": "holo3-122b-a10b",
           "instructions": "Do not browse. Answer in the required structured format with exactly one entry in the list.",
           "skills": ["h/answering"], "answer_format": FAILS},
    messages="What is 2+2?")
print(r.status, r.answer)   # completed None   <- silent
  • Failing session: 31e2b6e5-229c-48b9-9485-25e62e4aaac8 — completed, error_code: null, latest_answer: null
  • Passing session (string instead of enum): f8890af1-4d67-416b-a037-adc64b180c60 — valid structured answer

Bisected across ~18 sessions: subagents, custom tools, $ref/$defs, nullable fields, integer fields, schema size, and long descriptions were each eliminated; top-level enums pass; the failure requires the enum nested in an array item and the model actually emitting an entry (empty arrays slip through). The schema is standard JSON Schema; gpt-4o-mini under OpenAI strict mode fills it correctly.

Reproduction 2 — Models API (probabilistic, shows the mechanism)

Same model as the platform sessions (holo3-122b-a10b), response_format: {type: json_schema, strict: true}, schema above, 3 samples per cell:

  • enable_thinking: true: 5/6 samples corrupted (across enum and string variants). Actual message.content values:

    {"answer": "<loc_0><loc_0><loc_500...            <- GUI grounding tokens leaking into a string value
    {"answer": "../../../../../../tmp/tmpe0k118qz"   <- temp-file path surfacing in the answer
    {"answer": "\t\t\t\t\t... (~50 tabs)             <- tab flood, ends with finish_reason: length
    
  • enable_thinking: false: 3/3 clean, parseable, semantically correct.

  • holo3-1-35b-a3b shows the same pattern; worst case there leaked a markdown fence into a string value:

    {"answer": "}```json\n{ "  , "items": ...
    

The reasoning template is how agent sessions run, so the platform's answer action operates in the corrupting configuration. Enum-in-array is the construct where corruption crosses into hard validation failure most reliably (deterministically so on the platform, per Repro 1).

Expected

Either a schema-valid final answer, or a session that fails loudly: error_code: answer_validation (as documented), ideally with the rejected raw text attached for debugging.

Actual

status: completed, latest_answer: null, error_code: null. Nothing in the session events indicates an answer was attempted and rejected.

Environment

  • hai-agents 1.0.7 (Python), EU region (agp.eu.hcompany.ai)
  • Platform sessions and Models API repro: holo3-122b-a10b (mechanism also reproduced on holo3-1-35b-a3b)
  • Dates: 2026-07-18, session IDs above should be retrievable in your logs

Workaround (for anyone else who hits this)

Avoid enums inside array items: make the field a plain string and list the allowed values in its description (the passing session above is exactly this one-field swap). answer_format otherwise keeps working.

Since the corruption on the Models API wasn't strictly limited to enum schemas, for our own flow we went one step further and described the JSON shape in the agent's instructions without answer_format, validating client-side — either approach gets you unblocked.

Activity

  1. changed the title [-]Sessions quietly finish with no answer when `answer_format` has an enum inside a list of objects — and no error is raised[/-] [+]Sessions quietly finish with no answer when `answer_format` has an enum inside a list of objects, and no error is raised[/+] on Jul 18, 2026
  2. arthurkatcher commented on Jul 18, 2026

    @arthurkatcher
    Author

    Full bisection matrix behind the "~18 sessions" line in the report, with session IDs for log correlation. All sessions holo3-122b-a10b, EU region, 2026-07-18. "null" means the session ended completed with latest_answer: null and error_code: null.

    Schema feature bisection (solo agent unless noted):

    Session What varied Answer
    cc4a9001-67b6-4b33-8590-d2cdc5d0e9e1 flat 2-field schema valid
    4e7fe62f-0838-4980-a262-739ee1468cd0 flat schema, manager + subagent valid
    51528533-dc3e-4bb4-b795-5d64df263c40 flat schema, custom client tool valid
    67a2daff-a7f0-472a-b117-e1ce4bd2b348 flat schema, manager + subagent + tool valid
    e4906623-b29d-4748-a9ec-6a332f79adf4 flat schema, slow subagent (wake path) valid
    5b2516ee-9b61-4d7b-aed4-a821d93c5261 nested $ref object array, no enum valid
    d035f810-ac1c-42a9-95d4-f8911c2fd055 flat top-level enum valid
    3390a561-805a-4242-bf44-058a980ad592 nullable field (anyOf + default) valid
    be547cbb-43a5-47eb-9c52-a41d821e2549 flat integer field valid
    3bcb497f-227c-4682-bda6-2a2663bfc880 flat string control valid
    cf5798a7-d0c3-48e2-bc8c-3f30f64dbf2e string field in array item valid
    286a37f1-3f84-4ef7-bf84-e69e9f8f5f4a int field in array item (model returned []) valid
    bfdbc563-8dc5-46fa-a4c7-bcedb68b9e65 enums in array item (model returned []) valid
    dfe44286-1bad-47a6-82e3-2a5818a5aad0 enum in array item, entry emitted null
    bdc9480c-2b74-4be7-ba90-951bb5803dc7 array items with enum + int (report shape) null
    7c5a7201-2bd9-440e-947a-494e48e869dd full report schema, manager + subagent + tool null
    b5b4f3ac-8a7e-4629-8787-85fbb4945710 full report schema, solo null
    5dfd8a3f-9674-43b5-ae26-90e5992b31ee full schema minus its optional field null
    888b00fc-7001-473b-ba5f-5b5eba5a194a full schema minus all descriptions null

    Consistent rule across all rows: a session returns null exactly when the schema has an enum inside an array item and the model actually emits an entry. Empty arrays slip through, which is why this can look intermittent.

    Also the production-shaped sessions that originally led here (full report schema; manager + 2 subagents + custom tool): be9decd2-f711-4df7-8aa5-62aec199eef1 and 07584313-cbec-4532-8133-c557d581aa42, both null. Same agents with answer_format removed and the format described in instructions instead: d4bb5199-a7a5-4b4b-a23a-7c2c9c47f11f, valid answer.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions