claude-code - 💡(How to fix) Fix `--json-schema` with `"format": "uri"` silently disables synthetic structured-output tool [1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
anthropics/claude-code#57757Fetched 2026-05-11 03:26:13
View on GitHub
Comments
0
Participants
1
Timeline
3
Reactions
0
Participants
Timeline (top)
labeled ×3

When the schema passed to claude -p --json-schema … contains a string property with "format": "uri", the model declines to invoke the synthetic structured-output tool entirely. The requested value lands in the response envelope's result field as plain text instead, leaving structured_output: null.

Removing the format: "uri" annotation (or replacing the property's type) restores tool invocation. No other JSON Schema feature investigated has the same effect — title, description, additionalProperties, required-list shape, field name, ordering, nesting, and field-level descriptions all leave behavior unchanged.

  • claude --version: 2.1.136 (Claude Code)
  • Model: claude-opus-4-7[1m] (reproduces on claude-opus-4-6 too)
  • Reproduction rate: 100% across 16 controlled schema mutations + dozens of end-to-end pipeline runs

Root Cause

When the schema passed to claude -p --json-schema … contains a string property with "format": "uri", the model declines to invoke the synthetic structured-output tool entirely. The requested value lands in the response envelope's result field as plain text instead, leaving structured_output: null.

Removing the format: "uri" annotation (or replacing the property's type) restores tool invocation. No other JSON Schema feature investigated has the same effect — title, description, additionalProperties, required-list shape, field name, ordering, nesting, and field-level descriptions all leave behavior unchanged.

  • claude --version: 2.1.136 (Claude Code)
  • Model: claude-opus-4-7[1m] (reproduces on claude-opus-4-6 too)
  • Reproduction rate: 100% across 16 controlled schema mutations + dozens of end-to-end pipeline runs

Code Example

# URL Reporter

You receive a URL value in the user message and emit it as structured output.

---

{
  "type": "object",
  "required": ["url"],
  "properties": {
    "url": { "type": "string", "format": "uri" }
  }
}

---

{
  "type": "object",
  "required": ["url"],
  "properties": {
    "url": { "type": "string" }
  }
}

---

PROMPT="The URL is https://example.com/pr/42. Emit it as structured output."

claude -p "$PROMPT" \
  --agent agent.md \
  --output-format json \
  --no-session-persistence \
  --dangerously-skip-permissions \
  --json-schema "$(cat schema-bad.json)"

---

subtype:           success
structured_output: null
result:            "https://example.com/pr/42"

---

claude -p "$PROMPT" \
  --agent agent.md \
  --output-format json \
  --no-session-persistence \
  --dangerously-skip-permissions \
  --json-schema "$(cat schema-good.json)"

---

subtype:           success
structured_output: {"url": "https://example.com/pr/42"}
result:            "Emitted."

---

agent.md          - minimal system prompt (one paragraph)
schema-bad.json   - schema with "format": "uri"
schema-good.json  - schema without "format": "uri"
repro.sh          - bash runner that executes both tests
sample-output.txt - captured output from a real run

---

==========================================================
  NEGATIVE — schema with "format": "uri" (bug reproduces)
==========================================================
  subtype:            success
  structured_output:  None
  result:             'https://example.com/pr/42'

==========================================================
  POSITIVE — same schema without "format": "uri"
==========================================================
  subtype:            success
  structured_output:  {'url': 'https://example.com/pr/42'}
  result:             'Emitted.'
RAW_BUFFERClick to expand / collapse

Summary

When the schema passed to claude -p --json-schema … contains a string property with "format": "uri", the model declines to invoke the synthetic structured-output tool entirely. The requested value lands in the response envelope's result field as plain text instead, leaving structured_output: null.

Removing the format: "uri" annotation (or replacing the property's type) restores tool invocation. No other JSON Schema feature investigated has the same effect — title, description, additionalProperties, required-list shape, field name, ordering, nesting, and field-level descriptions all leave behavior unchanged.

  • claude --version: 2.1.136 (Claude Code)
  • Model: claude-opus-4-7[1m] (reproduces on claude-opus-4-6 too)
  • Reproduction rate: 100% across 16 controlled schema mutations + dozens of end-to-end pipeline runs

Self-contained reproduction

Three small files; two claude CLI invocations with identical flags except the schema content.

Files

agent.md

# URL Reporter

You receive a URL value in the user message and emit it as structured output.

schema-bad.json — has "format": "uri"

{
  "type": "object",
  "required": ["url"],
  "properties": {
    "url": { "type": "string", "format": "uri" }
  }
}

schema-good.json — identical except for the missing format annotation

{
  "type": "object",
  "required": ["url"],
  "properties": {
    "url": { "type": "string" }
  }
}

Negative test (reproduces the bug)

PROMPT="The URL is https://example.com/pr/42. Emit it as structured output."

claude -p "$PROMPT" \
  --agent agent.md \
  --output-format json \
  --no-session-persistence \
  --dangerously-skip-permissions \
  --json-schema "$(cat schema-bad.json)"

Observed envelope (relevant fields):

subtype:           success
structured_output: null
result:            "https://example.com/pr/42"

The synthetic structured-output tool is never invoked. The URL value the model was asked to emit lands in result as a plain string.

Positive test (works as expected)

Same command, only schema-bad.json swapped for schema-good.json:

claude -p "$PROMPT" \
  --agent agent.md \
  --output-format json \
  --no-session-persistence \
  --dangerously-skip-permissions \
  --json-schema "$(cat schema-good.json)"

Observed envelope:

subtype:           success
structured_output: {"url": "https://example.com/pr/42"}
result:            "Emitted."

Expected behavior

Both invocations should produce identical structured_output envelopes — {"url": "https://example.com/pr/42"}. JSON Schema's format keyword is, by spec (Draft-07 §7.1), an annotation: it should not affect whether the synthetic tool is invoked, only whether the produced value passes downstream validation.

Actual behavior

Adding "format": "uri" to a string property suppresses the synthetic tool entirely. The model writes the value the schema asked for into the result field as plain text and structured_output stays null. The CLI exits with subtype: success, so callers downstream cannot tell that structured emission silently failed.

Diagnostic notes

This was isolated by running 16+ controlled schema mutations through identical CLI invocations and comparing structured_output populated vs. null:

MutationResult
format: uri removed (any other change held)structured_output populated
Field type changed from string to integer (URL field becomes ID)populated
Field type changed to array of stringspopulated
Field type changed to string with enum constraintpopulated
Field renamed (e.g., pr_urllink / evidence / value) but format: uri keptnull (bug reproduces)
pr_url field nested inside an array-of-objects, format: uri retainednull
Schema-level description addednull (no help)
Field-level description addednull (no help)
additionalProperties: false addednull (no help)
Property reordered to lastnull (no help)
required reduced to ["outcome"] only, format kept on a separate optional fieldnull (no help)

The single attribute that determines emission is "format": "uri". This pattern persists across schemas with different titles, different field counts, different required-list shapes, and different surrounding properties.

Repro package contents

The accompanying repro.sh runs both the negative and positive tests back-to-back and summarizes the relevant envelope fields.

agent.md          - minimal system prompt (one paragraph)
schema-bad.json   - schema with "format": "uri"
schema-good.json  - schema without "format": "uri"
repro.sh          - bash runner that executes both tests
sample-output.txt - captured output from a real run

Sample run output:

==========================================================
  NEGATIVE — schema with "format": "uri" (bug reproduces)
==========================================================
  subtype:            success
  structured_output:  None
  result:             'https://example.com/pr/42'

==========================================================
  POSITIVE — same schema without "format": "uri"
==========================================================
  subtype:            success
  structured_output:  {'url': 'https://example.com/pr/42'}
  result:             'Emitted.'

Impact

This makes structured-output mode unusable for any schema modeling external resources (PR/MR URLs, document links, webhook callback URLs, signed-URL outputs, etc.) when authors follow JSON Schema best practices and annotate string fields with format: "uri". The only working remedy we found — omitting the annotation entirely — trades schema clarity for working tool invocation.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

FAQ

Expected behavior

Both invocations should produce identical structured_output envelopes — {"url": "https://example.com/pr/42"}. JSON Schema's format keyword is, by spec (Draft-07 §7.1), an annotation: it should not affect whether the synthetic tool is invoked, only whether the produced value passes downstream validation.

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

claude-code - 💡(How to fix) Fix `--json-schema` with `"format": "uri"` silently disables synthetic structured-output tool [1 participants]