Skip to content

fix(responses): default missing InputImageContent.detail during deserialization#546

Merged
64bit merged 1 commit into
64bit:mainfrom
ajcasagrande:ajc/default-input-image-detail
May 13, 2026
Merged

fix(responses): default missing InputImageContent.detail during deserialization#546
64bit merged 1 commit into
64bit:mainfrom
ajcasagrande:ajc/default-input-image-detail

Conversation

@ajcasagrande
Copy link
Copy Markdown
Contributor

  • default InputImageContent.detail to auto when missing in JSON input
  • add focused response-types integration tests covering both the
    EasyMessage and strict Item::Message(Input::User) deserialization paths

Closes #545.

InputImageContent.detail is documented as defaulting to auto, but without
#[serde(default)] any spec-compliant payload that omits detail (per
openai-python's ResponseInputImageParam, which marks detail
Optional[Literal["low","high","auto"]]) fails to deserialize. Because
InputItem is #[serde(untagged)], the single missing-field error rolls up
to data did not match any variant of untagged enum InputItem, which is
what spec-compliant clients hit in practice (full traceback in #545).

This mirrors the precedent set by #527 (EasyInputMessage.r#type,
WebSearchApproximateLocation.r#type) and uses the same test file
(tests/responses_input_item_serde.rs).

ImageDetail already derives Default with #[default] Auto, so the
fix is a single #[serde(default)] attribute — no Default impl needed.

Verification

  • cargo test -p async-openai --test responses_input_item_serde --features response-types → 4 passed (2 pre-existing + 2 new)
  • cargo fmt --check → clean
  • cargo clippy -p async-openai --features response-types --tests -- -D warnings → clean
  • End-to-end repro: against released v0.38.1 from crates.io, the payload below errors with data did not match any variant of untagged enum InputItem; against this branch the same payload deserializes successfully with detail defaulted to ImageDetail::Auto.
{
  "role": "user",
  "content": [
    {"type": "input_text", "text": "describe this"},
    {"type": "input_image", "image_url": "https://example.com/cat.png"}
  ]
}

Refs:

- default InputImageContent.detail to auto when missing in JSON input
- add focused response-types integration tests covering both the
  EasyMessage and strict Item::Message(Input::User) deserialization paths

InputImageContent.detail is documented as defaulting to `auto`, but
without #[serde(default)] any spec-compliant payload that omits it
(per openai-python's ResponseInputImageParam, which marks detail
Optional[Literal["low","high","auto"]]) fails to deserialize. Because
InputItem is #[serde(untagged)], the single missing-field error rolls
up to "data did not match any variant of untagged enum InputItem",
which is what spec-compliant clients hit in practice.

Closes 64bit#545.

Refs:
- openapi.documented.yml: ResponseInputImage (type required;
  image_url/file_id/detail all optional)
- openai-python: src/openai/types/responses/response_input_image_param.py
  (detail: Optional[Literal["low", "high", "auto"]])
- openai-node: src/resources/responses/responses.ts (detail?: 'low'|'high'|'auto')
- Prior fix in same spirit: 64bit#527
Copy link
Copy Markdown
Owner

@64bit 64bit left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for details and tests, appreciate it all!

PS: I still see detail to be Required

@64bit 64bit merged commit 7fdcd7f into 64bit:main May 13, 2026
99 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Multimodal Responses payload without detail fails to deserialize (InputImageContent.detail missing #[serde(default)])

2 participants