Skip to content

GLM-5.2 via OpenCode Go returns 400: messages.content should be a valid string #32821

Closed as not planned

Description

@Spirit597

Description

GLM-5.2 returns HTTP 400 "Input should be a valid string" for messages.content when called through OpenCode Go plan via cc-switch in Claude Code.

The request body sends content as [{"text": "..."}] array format, but the model returns a validation error expecting a plain string.

Error message:

API Error: 400 Error from provider: 2 request validation errors: Input should be a valid string, field: 'messages[1].content.str', value: [{'text': ...

Steps to reproduce

  1. Set up cc-switch with OpenCode Go as the provider for Claude Code
  2. Switch the active model to glm-5.2
  3. Send any text prompt to Claude Code
  4. Observe the HTTP 400 error returned from OpenCode Go backend

Plugins

None

OpenCode version

N/A (server-side issue — OpenCode Go backend)

cc-switch version

3.16

Screenshot and/or share link

Will attach if needed

Operating System

Ubuntu 24.04 LTS, Linux 6.14.0-37-generic x86_64

Terminal

Ghostty

Claude Code version

2.1.181

Activity

  1. github-actions commented on Jun 18, 2026

    @github-actions
    Contributor

    This issue might be a duplicate of an existing issue. Please check:

    If your issue is distinct (e.g. the GLM-5.2 failure path differs), please note that in the issue and we can track it separately.

  2. lexlian commented on Jun 19, 2026

    @lexlian

    @Spirit597 @MrMushrooooom , I fixed the issue with PR #32966.

    Root cause: GLM-5.2 (and Xiaomi/MiMo) require tool role messages[].content to be a plain string, not ContentPart[] array. This is the same root cause as #32613.

    Fix: Added a provider transform that flattens single-part tool results to strings for providers in the FLATTEN_TOOL_CONTENT_PROVIDERS list (mimo, glm, xiaomi). Extension point: add more provider IDs to the tuple to handle similar cases.

  3. Spirit597 commented on Jun 23, 2026

    @Spirit597
    Author

    Thanks for the quick turnaround on PR #32966, @lexlian. Before this gets treated as resolved, I have a few doubts — the issue is still open and I'm not convinced the fix covers the original failure path:

    1. Which layer is actually fixed? The report (and the duplicate-bot note on OpenCode Go: Xiaomi MiMo rejects list-type tool message content (400 text is not set) #32613) pins the root cause on the OpenCode Go backend relaying a list-type messages.content to a model that expects a string — i.e. server-side. PR fix(provider): flatten tool message content for MiMo/GLM/Xiaomi #32966 adds a transform on the opencode client side. For setups that never touch the opencode client — e.g. Claude Code → cc-switch local proxy → OpenCode Go → GLM-5.2 — would a client-side transform take effect at all? That's exactly the repro path, and it looks untouched.

    2. Scope vs. the actual error. Per your description, the PR flattens single-part tool-role content for FLATTEN_TOOL_CONTENT_PROVIDERS. But the error is messages[1].content.str, and the repro is "send any text prompt" — no tool call involved. Wouldn't a plain user/assistant message with array content still trigger the same 400? Tool-result flattening alone doesn't seem to cover that.

    3. Has it been verified? Was the fix tested against the original repro (cc-switch + OpenCode Go plan + glm-5.2, plain text prompt)? If it passes end-to-end now, confirming that on the issue before closing would help. If not, the server-side relay may be the real fix site.

    Happy to share request/response captures from the cc-switch → OpenCode Go path if that helps localize it.

  4. AXuanCreator commented on Jun 23, 2026

    @AXuanCreator

    same question, and not work at 0623
    my link: opencode go -> newapi -> cc-switch -> claude code

  5. lexlian commented on Jun 24, 2026

    @lexlian

    @Spirit597 @AXuanCreator This one is different from issue #32613 which I intended to fix.

    I tried the Claude Code → cc-switch local proxy (Local Routing) → OpenCode Go → GLM-5.2, and prompting in Claude Code can work, as shown in the following image. The key is to add OpenCode Go as provider for Claude Code(API format: OpenAI chat completion) and then enable Local Routing in CC Switch (as Claude Code uses Anthropic Messages API format).

    If this could not work, there could be some config issue or other local proxy software could be used.

    Image Image
  6. Spirit597 commented on Jun 25, 2026

    @Spirit597
    Author

    Update: After upgrading claude-code (v2.1.190, auto update) and cc-switch (v3.16.3), glm-5.2 via OpenCode Go is now working correctly. Plain text prompts no longer return 400 errors.

    Users on the latest claude-code + cc-switch should find this resolved. Thanks for the work on this!

  7. powerman commented on Jun 26, 2026

    @powerman

    I've fixed this issue by creating (and enabling in the config) ~/.claude-code-router/transformers/fix-glm52.js:

    module.exports = function () {
        return {
            name: 'fix-glm52',
            transformRequestIn(req) {
                if (req.messages && Array.isArray(req.messages)) {
                    const model = req.model || '';
                    if (model.includes('glm-5.2')) {
                        if (req.reasoning !== undefined) {
                            delete req.reasoning;
                        }
                        if (req.reasoning_effort !== undefined) {
                            delete req.reasoning_effort;
                        }
                        req.messages = req.messages.map((msg) => {
                            if (msg.content && Array.isArray(msg.content)) {
                                const textParts = msg.content
                                    .filter((part) => part.type === 'text')
                                    .map((part) => part.text);
                                const newContent = textParts.join('\n');
                                msg.content = newContent;
                            }
                            return msg;
                        });
                    }
                }
                return req;
            },
        };
    };
  8. powerman commented on Jun 26, 2026

    @powerman

    After upgrading claude-code (v2.1.190, auto update) and cc-switch (v3.16.3)

    I'm not using cc-switch, but upgrading claude to 2.1.190 does not fixed the issue for me.
    Transformer from previous message works with older claude (e.g. 2.1.181) just fine.

  9. github-actions commented on Aug 25, 2026

    @github-actions
    Contributor

    To stay organized issues are automatically closed after 60 days of no activity. If the issue is still relevant please open a new one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

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