Skip to content

[Question][SMG]Why is ChatMessage::Assistant.content optional and omitted instead of serialized as null? #18100

@IanM0one

Description

@IanM0one

I have a question about the definition of ChatMessage, specifically the Assistant variant in the chat.rs source.

The relevant code is here (from docs.rs):

https://docs.rs/crate/openai-protocol/1.0.0/source/src/chat.rs

In that file, the Assistant variant is defined like so:

#[serde(rename = "assistant")]
Assistant {
    #[serde(skip_serializing_if = "Option::is_none")]
    content: Option<MessageContent>,
    #[serde(skip_serializing_if = "Option::is_none")]
    name: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    tool_calls: Option<Vec<ToolCall>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    reasoning_content: Option<String>,
}

My questions

  1. Why is assistant.content typed as Option (instead of MessageContent) and annotated with #[serde(skip_serializing_if = "Option::is_none")]?
    From what I understand, this means that if content is None, the field will be omitted entirely in the JSON output, rather than being emitted as "content": null.
  2. Why is this behavior applied to assistant.content only, and not to other roles like system, user, or tool in the same ChatMessage type?

I’m asking because my downstream model supports assistant.content being null, but does not allow the assistant.content field to be completely absent.
With #[serde(skip_serializing_if = "Option::is_none")], when content is None the field is omitted from the serialized JSON, which causes compatibility issues in this setup.
So I’d like to confirm whether this behavior is intentional, and whether a missing content field is considered semantically equivalent to "content": null in this crate’s design.

Thanks in advance for any clarification!

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