Skip to content

@effect/ai-openai: generateObject fails when OpenAI Responses API returns duplicate output_text parts #6146

@chico2k

Description

@chico2k

What version of Effect is running?

effect: 3.21.0 @effect/ai: 0.35.0 @effect/ai-openai: 0.39.0

What steps can reproduce the bug?

Call LanguageModel.generateObject() with any structured schema via the OpenAI Responses API (/v1/responses). The bug is intermittent — it depends on OpenAI returning duplicate output messages.

const MySchema = Schema.Struct({
  name: Schema.String,
  amount: Schema.Number,
})

const result = yield* LanguageModel.generateObject({
  prompt: [{ role: "user", content: "Extract: Invoice from Acme Corp for €123.45" }],
  schema: MySchema,
})

This fails intermittently with a parseJson error when OpenAI's Responses API returns multiple identical OutputMessage items in the response.output array.

Affected models: observed with gpt-5.4-mini, also widely reported with gpt-4.1-mini, gpt-4o, and gpt-4.1 on the OpenAI community forums.

What is the expected behavior?

generateObject returns a parsed object matching the schema.

What do you see instead?

AiError: Generated object failed to conform to provided schema
└─ Encoded side transformation failure
   └─ parseJson
      └─ Transformation process failure
         └─ Unexpected non-whitespace character after JSON at position [N]

Using a custom Telemetry.CurrentSpanTransformer, we confirmed that the response contains duplicate text parts:

[response-metadata] { id: "resp_...", model: "gpt-5.4-mini-..." }
[text] {"name":"Acme Corp","amount":123.45}
[text] {"name":"Acme Corp","amount":123.45}    ← identical duplicate
[finish] { reason: "stop" }

resolveStructuredOutput in LanguageModel.ts (~L1059-1077) concatenates all text parts via text.join(""), producing:

{"name":"Acme Corp","amount":123.45}{"name":"Acme Corp","amount":123.45}

This is invalid JSON — two objects concatenated without a separator.

Additional information

This is a confirmed OpenAI API bug where the Responses API (/v1/responses) intermittently returns multiple OutputMessage items in response.output, each containing identical output_text content. OpenAI Support has acknowledged it.

References:

Where the issue is in @effect/ai-openai:

OpenAiLanguageModel.ts iterates over all items in response.output and pushes every output_text as a text part — no deduplication.

The OpenAI response object includes an output_text convenience property that returns just the text as a single string. The API docs recommend: "Rather than accessing the first item in the output array and assuming it's an assistant message...you might consider using the output_text property."

Suggested fixes (any of these would resolve it):

  1. (provider-level, recommended) Use response.output_text in @effect/ai-openai when available for structured output responses
  2. (provider-level) Deduplicate or take only the first message from response.output
  3. (consumer-level) In resolveStructuredOutput, use only the first text part instead of concatenating all

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions