Blog • AWS / Bedrock
Claude structured outputs on Amazon Bedrock already guarantee schema-shaped JSON—why do batch logs and copied chat still need a local three-step check?
On October 19, 2026 AWS announced structured outputs for Claude models on Amazon Bedrock: constrained decoding guided by JSON Schema at inference time, schema passed via output_config, strict tool use, and additionalProperties:false. Batch jobs and streaming responses are included.
A fuller structured-output path comparison is in the 2026 structured output guide. Schema-valid data still does not replace permission checks—see the agent schema-not-enough article. How JSON Schema spans tools and final answers is in why AI needs JSON Schema. This article covers only the three local steps after Bedrock guarantees shape.
- Bedrock requests attach JSON Schema under output_config.format with additionalProperties:false.
- The API guarantees the shape of one Invoke response—not log files, batch output files, or snippets copied from a console.
- Local pipeline: (1) JSON Schema validate; (2) JSON repair after stripping markdown fences; (3) JSONL line check for batch files.
- Use one TICKET_SCHEMA to validate API samples, log lines, and batch rows—catch bad enums, missing keys, and extra properties locally.
The decision: Bedrock structured outputs own API response shape; logs, batch files, and copied chat still need local schema validation, fence repair, and JSONL line checks.
What did Bedrock add for Claude on October 19?
AWS says in the official what's new post: Claude on Bedrock supports structured outputs with constrained decoding to match JSON Schema, plus strict tool use, batch, and streaming.
Technical details and sample requests are in the AWS Machine Learning blog post. Do not treat the API guarantee as the end of your log pipeline or compliance archive.
How do you attach JSON Schema in output_config?
Bedrock requests set output_config.format.type to json_schema and put the object definition in schema. Set additionalProperties:false on the root object, matching OpenAI Strict Schema habits. The sample below uses ticket_id, priority (enum), and summary.
{
"anthropic_version": "bedrock-2023-05-31",
"max_tokens": 1024,
"messages": [
{
"role": "user",
"content": "Return one support ticket as JSON."
}
],
"output_config": {
"format": {
"type": "json_schema",
"schema": {
"type": "object",
"additionalProperties": false,
"required": ["ticket_id", "priority", "summary"],
"properties": {
"ticket_id": { "type": "string" },
"priority": { "enum": ["low", "medium", "high"] },
"summary": { "type": "string", "maxLength": 200 }
}
}
}
}
}
Batch jobs often land JSONL in object storage—one record per line. Streaming responses stitched client-side may be pasted into tickets or chat. Those copies are not re-validated by Bedrock's decoder.
If the API guarantees shape, why validate locally?
The Invoke body is schema-shaped at Bedrock, but saved artifacts deform: log prefixes, CloudWatch escaping, ```json fences from the Playground, blank or truncated lines in batch files.
{
"ticket_id": "TCK-1042",
"priority": "high",
"summary": "Bedrock batch row passed constrained decoding"
}
If priority becomes urgent or an owner field appears, routing and SLA rules mis-fire. SAMPLE_BAD shows an out-of-range enum—catch that in your app with the same TICKET_SCHEMA.
{
"ticket_id": "TCK-1042",
"priority": "urgent",
"summary": "enum value not in schema"
}
Which TICKET_SCHEMA do you use locally?
Use JSON Schema to pin fields and enums. priority must be low, medium, or high; additionalProperties:false rejects undeclared keys. Passing only means the shape is legal, not that the record came from a trusted log.
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"additionalProperties": false,
"required": ["ticket_id", "priority", "summary"],
"properties": {
"ticket_id": {
"type": "string",
"description": "Support ticket ID, e.g. TCK-1042"
},
"priority": {
"enum": ["low", "medium", "high"]
},
"summary": {
"type": "string",
"maxLength": 200
}
}
}
| What you see | Schema | What to do locally |
|---|---|---|
| priority is urgent | Fails: enum does not include urgent. | Reject ingest or route to human review. |
| ticket_id is a number | Fails: type should be string. | Repair or drop that batch line. |
| extra owner field | Fails: additionalProperties:false. | Strip the field or reject the record. |
What does each step of the local pipeline fix?
Treat Bedrock as the online decoder and JSONNote as the offline QA bench. Keep the order: schema-shaped JSON first, then fence repair, then JSONL line checks.
| Step | What it handles |
|---|---|
| JSON Schema validate | Single API samples, objects cut from logs, strings after fence repair. |
| JSON repair (strip markdown fences) | ```json ... ``` blocks copied from Playground or chat. |
| JSONL line check | Bedrock batch output files: each line must parse and pass schema on its own. |
How do you run the three steps in JSONNote?
- 1Step 1: Schema validate
Open JSON Schema. Paste TICKET_SCHEMA in the first field and SAMPLE_OK or JSON from logs in the second. Bad enums, missing keys, and extras should highlight immediately.
- 2Step 2: Fence repair
Open JSON Repair. Paste chat copied with ```json fences, strip fences, then run Schema validate again.
- 3Step 3: JSONL line check
Open JSONL tool. Upload Bedrock batch output and confirm each line parses; use TICKET_SCHEMA to see whether a bad line is enum or truncation.
Common questions
Can I skip local validation with Bedrock structured outputs?
No. The API only guarantees the current Invoke body. Logs, batch files, copied chat, and caches need the same schema validated again in your app.
How do strict tool use and output_config schema relate?
Both use JSON Schema during decoding, but at different layers: tool arguments use tool schemas, final text uses output_config. Store both schemas separately for local checks—do not mix them in one log field.
If one JSONL line fails, must I rerun the whole batch?
Not necessarily. Use the JSONL tool for line numbers and TICKET_SCHEMA to see enum, truncation, or syntax failures. Retry only failed lines or re-Invoke—cheaper than a full batch rerun.
Should local schema also set additionalProperties:false?
Yes. Keep Bedrock request schema and local TICKET_SCHEMA aligned—otherwise API pass and ingest rules can disagree.
Do streaming responses need JSONL checks too?
For streaming, stitch one response then Schema validate and Repair. JSONL checks apply when batch jobs land multi-line files.
Summary
Bedrock structured outputs lock Claude API responses to JSON Schema; batch files, stitched streaming, logs, and paste still break shape.
The decision: online, trust Bedrock output_config; offline, validate with the same TICKET_SCHEMA, Repair fences, JSONL-check batch lines.
Next: Schema-validate Bedrock samples, Repair copied fences, JSONL-check batch files.