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.

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.

Bedrock Invoke snippet: JSON Schema inside output_config.
{
  "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.

A schema-conform Bedrock response sample (SAMPLE_OK).
{
  "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.

Failed sample with a bad enum (SAMPLE_BAD).
{
  "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.

TICKET_SCHEMA aligned with Bedrock output_config.
{
  "$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 seeSchemaWhat to do locally
priority is urgentFails: enum does not include urgent.Reject ingest or route to human review.
ticket_id is a numberFails: type should be string.Repair or drop that batch line.
extra owner fieldFails: 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.

StepWhat it handles
JSON Schema validateSingle API samples, objects cut from logs, strings after fence repair.
JSON repair (strip markdown fences)```json ... ``` blocks copied from Playground or chat.
JSONL line checkBedrock batch output files: each line must parse and pass schema on its own.

How do you run the three steps in JSONNote?

  1. 1
    Step 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.

  2. 2
    Step 2: Fence repair

    Open JSON Repair. Paste chat copied with ```json fences, strip fences, then run Schema validate again.

  3. 3
    Step 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.

Back to the blog