anthropics / anthropics/claude-code
[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
- 主要语言
- Python
- 星标
- 145k
- 派生
- 23.1k
- PR 合并指标
- PR 指标待抓取
描述
### Preflight Checklist
- [x] I have searched [existing issues](https://github.com/anthropics/claude-code/issues?q=is%3Aissue%20state%3Aopen%20label%3Abug) 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
```shell
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":"","ANTHROPIC_DEFAULT_OPUS_MODEL":"glm-5.3"},"model":"opus"}
```
2. Start `claude` (interactive) with 2.1.265 or 2.1.266 and send any prompt: 400 / 1210 on every turn.
3. Run `claude -p "Say OK"` with the same settings: works (print mode omits the Artifact tool).
4. Start the same interactive session with 2.1.263: works (the Artifact tool is sent, but without the `field` pattern).
5. 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: ' \
-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).
贡献指南
这个仓库没有索引到贡献指南
调研方向
The issue identifies the Artifact tool's input_schema.properties.field pattern as the minimal failing construct; start by locating where interactive-mode tools are assembled and compare that schema with print mode and version 2.1.263. Reproduce against the standalone curl/backend case, then verify that interactive requests no longer receive 400 while the Artifact tool remains valid and ordinary Anthropic requests are unaffected.
由索引模型根据 Issue 内容生成。
评估
- 领域
- api, backend
- Issue 类型
- 缺陷
- 难度
- 4/5
- 预计耗时
- 3-5 天
- 活跃度
- 活跃
- 描述清晰度
- 描述清楚
- 新手友好度
- 58/100