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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions