[BUG] Since 2.1.265 the Artifact tool's input_schema carries a `pattern` with Unicode property escapes (\p{Cc}); Anthropic-compatible third-party backends reject every interactive request with 400

Status Open
Reported on v2.1.265
Maintainer reply None cached
Activity 4 comments · opened Sep 9, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

Interactive Claude Code sessions with ANTHROPIC_BASE_URL pointed at an Anthropic-compatible third-party backend (Z.AI GLM, via a local proxy; reproduced with plain curl against the backend too) fail on every turn with HTTP 400. claude -p against the same backend works.

Bisecting the two captured request bodies shows the trigger is the tools array: interactive mode includes the built-in Artifact tool, and since 2.1.265 the field property of its input_schema carries this pattern:

^(?!__.*__$)[^\p{Cc}\p{Cf}\p{Zl}\p{Zp}"\\./[\]]{1,200}$

Removing that single pattern makes the identical request succeed. The other five patterns in the same schema are accepted, so the backend's problem is specifically the Unicode property escapes (\p{...}). It is the only pattern in Claude Code's whole tool set that uses them.

2.1.263 and earlier send the Artifact tool without that pattern and work. So every user of an Anthropic-compatible backend lost interactive Claude Code on upgrade to 2.1.265, while long-running older sessions kept working, which made this hard to attribute.

I know the backend is at fault for not accepting valid ECMA-262 syntax (reported to them separately), but Claude Code sends this schema to any base URL, and one non-portable pattern in one property breaks the whole product on third-party backends.

What Should Happen?

Either of:

  • an ASCII-only pattern for Artifact.input_schema.properties.field (the intent, "no control characters, quotes, backslashes, dots, slashes or brackets, not __x__", can be expressed without \p{...}), or
  • omit the Artifact tool from the request when the base URL is not Anthropic's / the artifact capability is unavailable.

Interactive sessions should then behave like -p does today against these backends.

Error Messages/Logs

API Error: 400 [glm/glm-5.3] [400]: {"type":"error","error":{"type":"invalid_request_error","code":"1210","message":"[1210][Invalid API parameter, please check the documentation.][202609090759179161046158a5442f]"},"request_id":"202609090759179161046158a5442f"} (reset after 30s)

Steps to Reproduce

  1. Point Claude Code at an Anthropic-compatible backend whose schema validator does not support \p{...} (Z.AI's https://api.z.ai/api/anthropic does not), e.g. in settings.json:

``json
{"env":{"ANTHROPIC_BASE_URL":"https://api.z.ai/api/anthropic","ANTHROPIC_AUTH_TOKEN":"<key>","ANTHROPIC_DEFAULT_OPUS_MODEL":"glm-5.3"},"model":"opus"}
``

  1. Start claude (interactive) with 2.1.265 or 2.1.266 and send any prompt: 400 / 1210 on every turn.
  2. Run claude -p "Say OK" with the same settings: works (print mode omits the Artifact tool).
  3. Start the same interactive session with 2.1.263: works (the Artifact tool is sent, but without the field pattern).
  4. Capture the interactive request body (any logging proxy), replay it with the Artifact tool's pattern keywords stripped: 200. Replay it with only the field pattern removed: 200. Keep only that pattern and drop the other five: 400.

Standalone repro without Claude Code, showing the backend rejects exactly this construct:

curl -s https://api.z.ai/api/anthropic/v1/messages -H 'content-type: application/json' -H 'anthropic-version: 2023-06-01' -H 'x-api-key: <KEY>' \
  -d '{"model":"glm-5.3","max_tokens":32,"messages":[{"role":"user","content":"Say OK"}],"tools":[{"name":"probe","description":"probe","input_schema":{"type":"object","properties":{"field":{"type":"string","pattern":"^[^\\p{Cc}]{1,200}$"}}}}]}'

returns 400 / 1210; without pattern it returns 200.

Workaround that restores interactive use: "permissions": {"deny": ["Artifact"]} in settings.json removes the tool from the request (verified: 33 -> 32 tools, 200).

Claude Model

Not sure / Multiple models

Is this a regression?

Yes, this worked in a previous version

Last Working Version

2.1.263 (Claude Code)

Claude Code Version

2.1.266 (Claude Code); also reproduced on 2.1.265

Platform

Other

Operating System

macOS

Terminal/Shell

Other

Additional Information

Platform detail: Anthropic-compatible third-party backend (Z.AI GLM glm-5.3) behind a local Anthropic-compatible proxy (9router); the standalone curl above hits the backend directly. Terminal: WezTerm. macOS 26 on Apple Silicon.

Version bracket, same playbook, same prompt, interactive:

  • 2.1.238, 2.1.252, 2.1.261, 2.1.263: Artifact tool sent, no \p{..} pattern in it, HTTP 200
  • 2.1.265, 2.1.266: Artifact tool sent with the field pattern, HTTP 400 / 1210

Bisection of the failing body (one thing changed at a time): swapping in print-mode tools fixes it; adding only Artifact to the print-mode tool list breaks it (AskUserQuestion, EnterPlanMode, ExitPlanMode, SendFeedback individually do not); stripping propertyNames, prefixItems, additionalProperties, anyOf, const or maxLength from the Artifact schema does not help; stripping pattern does; of the six distinct patterns only the field one fails.

Related: #84056 (interactive-only 400 from input_schema keywords on a third-party backend).

View original on GitHub ↗

3 Comments

adideveloper06 · 5 days ago

Also affected — confirming this is present on 2.1.266 as well (regression first shipped in 2.1.265; 2.1.263 is the last working build here). Same report also left on #92969, which is currently labeled duplicate of this issue.

Environment

  • Claude Code 2.1.266, native Linux build on WSL2 (Ubuntu)
  • Provider: DeepSeek Anthropic-compatible endpoint (ANTHROPIC_BASE_URL=https://api.deepseek.com/anthropic), model deepseek-v4-flash[1m]

Symptoms

  • Every interactive request fails instantly with 400 Invalid schema for function 'Artifact': "…" is not a "regex" — even a plain "hi". Every new session, in any directory; no workaround flag.
  • The failing pattern from the error: ^(?!__.*__$)[^\p{Cc}\p{Cf}\p{Zl}\p{Zp}"\\./[\]]{1,200}$
  • Print mode (claude -p) works — consistent with the Artifact tool not being sent there.

Minimal repro (single /v1/messages request with one tool whose pattern is set):

  • pattern shipped by ≤ 2.1.263 → 200 OK
  • pattern shipped by 2.1.265/2.1.266 → 400 … is not a "regex"
  • lookahead-only and \p{...}-only variants each pass alone → it's the combined negated class that strict validators reject

DeepSeek advertises /anthropic as Claude Code-compatible, so this breaks every DeepSeek + Claude Code user on 2.1.265/2.1.266. A fix on either side resolves it: drop \p{...} / use explicit code-point ranges, or withhold pattern on non-first-party endpoints. Happy to share logs or the full repro payload.

nadirvishun · 4 days ago

Temporary workaround for native Windows installation (non-npm): roll back to v2.1.263

  • Download claude-win32-x64.zip from v2.1.263, and extract it to get claude.exe.
  • Locate the claude.exe directory in your system: C:\Users\Username\.local\bin, and back up the current claude.exe as claude.exe.old.2.1.266
  • Copy the newly downloaded claude.exe to the current directory.
  • Run claude again; the version will now have reverted to 2.1.263.
deadship2003 · 4 days ago

Independent confirmation + a few data points that may help others via search:

Environment: 2.1.266, native install, WSL2, ANTHROPIC_BASE_URL → a new-api relay whose glm-5.3 channel forwards to the GLM native API.

Two error surfaces, one trigger — depending on which upstream the relay routes to, the same request fails as either:

  • API Error: 400 [1210][API 调用参数有误,请检查文档。] (glm-5.3 native path), or
  • API Error: 400 Invalid schema for function 'Artifact': "^(?!__.*__$)[^\p{Cc}\p{Cf}\p{Zl}\p{Zp}\"\\\\./[\\]]{1,200}$" is not a "regex" (relay's OpenAI-compat conversion path)

A minimal A/B against the same endpoint confirms the pattern is the sole trigger: an identical tool definition without the pattern keyword → 200 OK; with it → 400.

Workaround confirmed end-to-end — in ~/.claude/settings.json (user-level settings; a project-level .claude/settings.json works too), merge a deny list into the existing permissions block:

{
  "permissions": {
    "deny": ["Artifact", "ArtifactComments", "ArtifactData", "ArtifactCheck"]
  }
}

The denied tool is dropped from the request entirely, so the validator never sees the pattern. Takes effect on the next session you start — already-running sessions keep the tool in their context. Denying just "Artifact" as in the OP also suffices; I denied the whole family defensively. Verified with a fresh interactive TUI session through the same relay: zero errors, normal responses.

Session-type discriminator for triage: SDK-spawned sessions (entrypoint=sdk-cli, e.g. bridges driving Claude Code through the SDK) and claude -p never ship the tool and keep working — handy for telling this regression apart from a relay-side outage.

Pinning caveat for the 2.1.263 downgrade path: "autoUpdates": false in .claude.json did not stop the native installer — both 2.1.265 and 2.1.266 auto-installed overnight. Staying on 2.1.263 requires DISABLE_AUTOUPDATER=1 (env), not just the setting.

Showing cached comments. Read the full discussion on GitHub ↗