Skip to content

Studio: accept system-role messages in Claude Code requests#6006

Merged
danielhanchen merged 6 commits into
unslothai:mainfrom
Imagineer99:feat/anthropic-system-message
Jun 5, 2026
Merged

Studio: accept system-role messages in Claude Code requests#6006
danielhanchen merged 6 commits into
unslothai:mainfrom
Imagineer99:feat/anthropic-system-message

Conversation

@Imagineer99
Copy link
Copy Markdown
Collaborator

@Imagineer99 Imagineer99 commented Jun 4, 2026

Summary

Fixes #6001

Newer Claude Code versions can send system instructions as role: "system" entries inside the messages array when calling /v1/messages. The Anthropic Messages schema only allows user and assistant roles in messages, so Studio rejected those requests with a 422 before the route could translate them.

This PR normalizes misplaced system-role messages during request validation by moving their content into the top-level Anthropic system field.

Before:
image

After:
image

Testing

/home/samle/.unsloth/studio/unsloth_studio/bin/python -m pytest -s studio/backend/tests/test_anthropic_messages.py -q

@Imagineer99 Imagineer99 changed the title Studio: accept system-role messages in Anthropic Messages requests Studio: accept system-role messages in Anthropic requests Jun 4, 2026
@Imagineer99 Imagineer99 changed the title Studio: accept system-role messages in Anthropic requests Studio: accept system-role messages in Anthropic/Claude Code requests Jun 4, 2026
@Imagineer99 Imagineer99 changed the title Studio: accept system-role messages in Anthropic/Claude Code requests Studio: accept system-role messages in Claude Code requests Jun 4, 2026
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces normalization for Anthropic system messages by extracting system-role messages from the messages list and merging them into the top-level system field. The feedback identifies a potential bug where an explicit null content value in a system message could result in a literal "None" string being used as the system prompt, and provides a code suggestion to handle None values defensively.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread studio/backend/models/inference.py
Imagineer99 and others added 2 commits June 5, 2026 10:04
…slothai#6006

Treat a system-role message with null content as empty instead of the
literal string "None", and skip None blocks inside list content. Adds a
regression test.
@danielhanchen
Copy link
Copy Markdown
Member

Pushed a small follow-up (921e314) to harden _anthropic_content_to_system_text against null content, which also resolves the review note from the bot.

Before this, a {"role": "system", "content": null} entry hit message.get("content", ""), which returns None (the key is present, so the "" default never applies), then fell through to str(content) and injected the literal string "None" into the system prompt. The same happened for None blocks inside list content.

The fix returns "" for null content and skips None blocks, so they are dropped instead of polluting the prompt:

if content is None:  # null content must not become the literal "None"
    return ""
...
if block is not None:
    parts.append(str(block))

Added test_system_role_message_with_null_content_ignored as a regression. Full suite is green:

python -m pytest studio/backend/tests/test_anthropic_messages.py -q
86 passed

Thanks for the fix, this is a clean approach. Hoisting in-array system messages into the top level system field is the right call since the downstream anthropic_messages_to_openai converter only reads system and has no system branch in its per message loop, so widening the role literal alone would have left the content stranded.

@Imagineer99 Imagineer99 marked this pull request as ready for review June 5, 2026 11:23
@danielhanchen danielhanchen merged commit fe604fd into unslothai:main Jun 5, 2026
25 of 27 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.

API error 422..when using claude..system or role "user", "assistant"

2 participants