{"record":{"id":"5d038d912b7531e0","repo":"BoundaryML/baml","slug":"invalid-client-property-should-have-been-a-anthropic","errorCode":null,"errorMessage":"Invalid client property. Should have been a anthropic property but got: {}","messagePattern":"Invalid client property\\. Should have been a anthropic property but got: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"engine/baml-runtime/src/internal/llm_client/primitive/anthropic/anthropic_client.rs","lineNumber":60,"sourceCode":"    context: RenderContext_Client,\n    features: ModelFeatures,\n    properties: ResolvedAnthropic,\n\n    // clients\n    client: reqwest::Client,\n}\n\n// resolves/constructs PostRequestProperties from the client's options and runtime context, fleshing out the needed headers and parameters\n// basically just reads the client's options and matches them to needed properties or defaults them\nfn resolve_properties(\n    provider: &ClientProvider,\n    properties: &UnresolvedClientProperty<()>,\n    ctx: &RuntimeContext,\n) -> Result<ResolvedAnthropic, anyhow::Error> {\n    let properties = properties.resolve(provider, &ctx.eval_ctx(false))?;\n\n    let ResolvedClientProperty::Anthropic(props) = properties else {\n        anyhow::bail!(\n            \"Invalid client property. Should have been a anthropic property but got: {}\",\n            properties.name()\n        );\n    };\n\n    Ok(props)\n}\n// getters for client info\nimpl WithRetryPolicy for AnthropicClient {\n    fn retry_policy_name(&self) -> Option<&str> {\n        self.retry_policy.as_deref()\n    }\n}\n\nimpl WithClientProperties for AnthropicClient {\n    fn allowed_metadata(&self) -> &AllowedRoleMetadata {\n        &self.properties.allowed_metadata\n    }","sourceCodeStart":42,"sourceCodeEnd":78,"githubUrl":"https://github.com/BoundaryML/baml/blob/bd85ce9dee1463ff04d27efd20531013a4ff46c1/engine/baml-runtime/src/internal/llm_client/primitive/anthropic/anthropic_client.rs#L42-L78","documentation":"resolve_properties expects the resolved client property block to be an Anthropic-specific property type; when the resolved variant is anything else, BAML bails with this type error naming what it got instead. It is an internal configuration-shape mismatch between the provider and the parsed client property.","triggerScenarios":"Declaring a client with provider \"anthropic\" whose options/properties resolve to a non-Anthropic ResolvedClientProperty variant — e.g. misconfigured properties block, wrong provider string, or custom properties that resolve to a generic variant.","commonSituations":"Copy-pasted client config from another provider (openai/aws) with provider renamed to anthropic but options shape unchanged; plugin/dynamic property resolution returning the wrong variant; version mismatch where anthropic options schema changed.","solutions":["Check that provider is exactly \"anthropic\" and the options block matches Anthropic's schema (api_key, model, etc.)","Remove foreign options fields copied from other providers","Ensure dynamic property injection returns an Anthropic-shaped property object","Pin/align the BAML runtime/CLI versions so the anthropic property parser matches"],"exampleFix":"// before (baml)\nclient \"claude\" {\n  provider anthropic\n  options { api_key env.OPENAI_API_KEY base_url \"https://api.openai.com\" } // openai-shaped options\n}\n// after\nclient \"claude\" {\n  provider anthropic\n  options { api_key env.ANTHROPIC_API_KEY model \"claude-3-5-sonnet-latest\" }\n}","handlingStrategy":"validation","validationCode":"// baml-src check or runtime config validation\nfunction validateAnthropicClient(cfg) {\n  if (cfg.provider !== 'anthropic') throw new Error('provider must be anthropic');\n  for (const k of Object.keys(cfg.options)) {\n    if (!['api_key','model','base_url','max_tokens','temperature'].includes(k))\n      throw new Error(`unknown anthropic option: ${k}`);\n  }\n}","typeGuard":"const isAnthropicProps = (p) => p && typeof p === 'object' && p.type === 'anthropic_properties';","tryCatchPattern":"try {\n  return await b.functions.F(x);\n} catch (e) {\n  if (/Invalid client property/.test(String(e))) {\n    throw new Error('Fix clients.baml: anthropic provider needs anthropic-shaped options');\n  }\n  throw e;\n}","preventionTips":["Never copy options blocks between providers without adapting them","Validate client configs with `baml-cli dev` test generation before shipping","Keep provider string and options schema in sync","Pin BAML versions across services"],"tags":["configuration","anthropic","type-mismatch"],"backgroundTag":"config-type-mismatch","analyzedSha":"bd85ce9dee1463ff04d27efd20531013a4ff46c1","analyzedAt":"2026-09-12T03:38:25.718Z","contentChangedAt":"2026-09-12T03:38:25.718Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}