{"record":{"id":"e9b1fb4e11b7f3c0","repo":"JuliusBrussee/caveman","slug":"wire-dialect-q-must-be-anthropic-or-empty","errorCode":null,"errorMessage":"wire dialect %q must be \"anthropic\" or empty","messagePattern":"wire dialect %q must be \"anthropic\" or empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"proxy/providers/openaicompat/openaicompat.go","lineNumber":348,"sourceCode":"// usage/cost telemetry keeps using the shared OpenAI-shape parser.\nfunc NewNamed(name, baseURL string, forwardHeaders ...string) (providers.Adapter, error) {\n\treturn NewNamedWithWireDialect(name, baseURL, \"\", forwardHeaders...)\n}\n\n// wireDialectUsageProvider maps a configured wire dialect to the provider whose\n// usage parser implements it. \"\" is the default OpenAI-shape parser.\nvar wireDialectUsageProvider = map[string]string{\n\t\"\":          \"\",\n\t\"anthropic\": \"anthropic\",\n}\n\n// ValidateWireDialect rejects dialect values no named mount can honor. It is\n// exported so the config loader fails at startup rather than silently parsing\n// an Anthropic-dialect upstream with the OpenAI-shape rules — the exact\n// misclassification issue #1026 reports.\nfunc ValidateWireDialect(dialect string) error {\n\tif _, ok := wireDialectUsageProvider[dialect]; !ok {\n\t\treturn fmt.Errorf(\"wire dialect %q must be \\\"anthropic\\\" or empty\", dialect)\n\t}\n\treturn nil\n}\n\n// NewNamedWithWireDialect builds a named mount whose upstream speaks a\n// different wire grammar than the mount's OpenAI-compatible identity.\n// \"anthropic\" is for an upstream that answers the Anthropic Messages protocol\n// on the mount. It changes two things and nothing else:\n//\n//   - USAGE ACCOUNTING parses with the Anthropic dialect (Base.UsageProvider):\n//     the usage block reports input_tokens EXCLUSIVE of cache reads/writes, so\n//     the OpenAI-shape contradiction check reads a warm cache as malformed and\n//     drops every such row from token accounting (issue #1026).\n//   - COMPRESSION ZONES follow the Anthropic Messages grammar on Messages-path\n//     requests and keep the OpenAI grammar on every other path (see\n//     anthropicWireZones): the Anthropic extractor keys the live/frozen\n//     boundary on the request's own cache_control breakpoints.\n//","sourceCodeStart":330,"sourceCodeEnd":366,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/3ee70a102609e550bd2e68004bf5990a9341c851/proxy/providers/openaicompat/openaicompat.go#L330-L366","documentation":"ValidateWireDialect rejects wire_dialect values the named compat mount cannot honor. Only \"anthropic\" or an empty string (default OpenAI shape) are accepted; anything else would cause the mount to parse an upstream's responses with the wrong wire grammar. Exported so the config loader fails at startup (issue #1026: Anthropic-dialect upstream silently misclassified).","triggerScenarios":"Config sets wire_dialect to a value not present in wireDialectUsageProvider — e.g. wire_dialect = \"openai\", \"gemini\", \"Ollama\", or a typo like \"anthropic \" — and validateCompat or NewNamedWithWireDialect calls ValidateWireDialect.","commonSituations":"Typo or casing mistake in config wire_dialect; copying a mount config that used a dialect name from another proxy; assuming other wire grammars are supported when only anthropic is.","solutions":["Set wire_dialect to \"anthropic\" if the upstream speaks the Anthropic Messages API, or remove the key entirely for OpenAI-shaped upstreams.","Fix casing/spelling exactly: lowercase \"anthropic\".","Remove the wire_dialect line if the upstream is OpenAI-compatible and no override is needed.","Check the proxy docs/version for the accepted dialect list — only \"anthropic\" and empty are valid."],"exampleFix":"# before\n[[compat_mount]]\nname = \"claude\"\nwire_dialect = \"Anthropic\"\n# after\n[[compat_mount]]\nname = \"claude\"\nwire_dialect = \"anthropic\"","handlingStrategy":"validation","validationCode":"valid := dialect == \"\" || dialect == \"anthropic\"\nif !valid {\n    return fmt.Errorf(\"unsupported wire_dialect %q; use \\\"anthropic\\\" or omit\", dialect)\n}","typeGuard":null,"tryCatchPattern":"if err := openaicompat.ValidateWireDialect(cfg.WireDialect); err != nil {\n    log.Fatalf(\"mount %s: %v\", cfg.Name, err)\n}","preventionTips":["Only ever write wire_dialect = \"anthropic\" or omit the key.","Lowercase dialect values exactly as documented.","Run the config loader's validation before deploying."],"tags":["go","proxy","config","wire-dialect","validation"],"backgroundTag":"invalid-enum-value","analyzedSha":"3ee70a102609e550bd2e68004bf5990a9341c851","analyzedAt":"2026-09-20T15:53:39.229Z","contentChangedAt":"2026-09-20T15:53:39.229Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}