Bug
anthropic.JSONOutputFormatParam declares:
// The properties Schema, Type are required.
type JSONOutputFormatParam struct {
Schema map[string]any `json:"schema,omitzero" api:"required"`
// This field can be elided, and will marshal its zero value as "json_schema".
Type constant.JSONSchema `json:"type" default:"json_schema"`
paramObj
}
The comment promises the zero value will marshal as "json_schema". In practice, the field is elided entirely from the marshaled body.
Reproduction
SDK version: v1.33.0. Go: go1.25.0. OS: Windows.
params := anthropic.MessageNewParams{
Model: "claude-sonnet-4-6",
MaxTokens: 100,
Messages: []anthropic.MessageParam{
anthropic.NewUserMessage(anthropic.NewTextBlock("hi")),
},
OutputConfig: anthropic.OutputConfigParam{
Format: anthropic.JSONOutputFormatParam{
Schema: map[string]any{"type": "object", "properties": map[string]any{}},
},
},
}
Captured request body via a logging RoundTripper:
"output_config":{"format":{"schema":{"type":"object","properties":{}}}}
The Python SDK (anthropic 0.92.0) on the same params produces:
"output_config":{"format":{"type":"json_schema","schema":{...}}}
Setting Type: constant.JSONSchema("json_schema") explicitly does not change the output (still elided). option.WithJSONSet("output_config.format.type", "json_schema") also does not insert the field.
Impact
When output_config.format.type is missing, the Anthropic API silently hangs the request rather than returning a 400. The SDK's CalculateNonStreamingTimeout fires after 10 minutes, returning context deadline exceeded. This is reproducible on claude-sonnet-4-6 with a real prompt; trivial requests sometimes complete (likely a different server-side fast path).
In our case, the same prompt and data run fine in seconds via the Python SDK and time out at 10 minutes via Go, with the only difference being the missing type field.
Workaround
A custom http.RoundTripper that injects the missing field into outgoing /v1/messages bodies:
const missing = `"format":{"schema":`
const fixed = `"format":{"type":"json_schema","schema":`
body = bytes.Replace(body, []byte(missing), []byte(fixed), 1)
Suggested fix
Either:
- Make the encoder honor the
default struct tag so the zero value of Type marshals as "json_schema".
- Or drop the elision and always emit the field.
Happy to provide a packet capture or any additional detail.
Bug
anthropic.JSONOutputFormatParamdeclares:The comment promises the zero value will marshal as
"json_schema". In practice, the field is elided entirely from the marshaled body.Reproduction
SDK version:
v1.33.0. Go:go1.25.0. OS: Windows.Captured request body via a logging
RoundTripper:The Python SDK (
anthropic0.92.0) on the same params produces:Setting
Type: constant.JSONSchema("json_schema")explicitly does not change the output (still elided).option.WithJSONSet("output_config.format.type", "json_schema")also does not insert the field.Impact
When
output_config.format.typeis missing, the Anthropic API silently hangs the request rather than returning a 400. The SDK'sCalculateNonStreamingTimeoutfires after 10 minutes, returningcontext deadline exceeded. This is reproducible onclaude-sonnet-4-6with a real prompt; trivial requests sometimes complete (likely a different server-side fast path).In our case, the same prompt and data run fine in seconds via the Python SDK and time out at 10 minutes via Go, with the only difference being the missing type field.
Workaround
A custom
http.RoundTripperthat injects the missing field into outgoing/v1/messagesbodies:Suggested fix
Either:
defaultstruct tag so the zero value ofTypemarshals as"json_schema".Happy to provide a packet capture or any additional detail.