{"record":{"id":"52e9f45610d3e8a3","repo":"BoundaryML/baml","slug":"encoding-client-options-w","errorCode":null,"errorMessage":"encoding client options: %w","messagePattern":"encoding client options: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"engine/language_client_go/pkg/rawobjects_client_registry.go","lineNumber":43,"sourceCode":"\t\tc.clients = make(clientRegistryMap)\n\t}\n\n\tc.clients[name] = clientProperty{\n\t\tprovider: provider,\n\t\toptions:  options,\n\t}\n}\n\nfunc (c *ClientRegistry) SetPrimaryClient(name string) {\n\tc.primary = &name\n}\n\nfunc encodeClientRegistry(clientRegistryVal *ClientRegistry) (*cffi.HostClientRegistry, error) {\n\tclientOffsets := make([]*cffi.HostClientProperty, 0, len(clientRegistryVal.clients))\n\tfor name, client := range clientRegistryVal.clients {\n\t\toptions, err := serde.EncodeMapEntries(client.options, \"client options\")\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"encoding client options: %w\", err)\n\t\t}\n\t\tclientOffsets = append(clientOffsets, &cffi.HostClientProperty{\n\t\t\tName:        name,\n\t\t\tProvider:    client.provider,\n\t\t\tRetryPolicy: client.retryPolicy,\n\t\t\tOptions:     options,\n\t\t})\n\t}\n\n\tclients := cffi.HostClientRegistry{\n\t\tClients: clientOffsets,\n\t\tPrimary: clientRegistryVal.primary,\n\t}\n\n\treturn &clients, nil\n}\n","sourceCodeStart":25,"sourceCodeEnd":60,"githubUrl":"https://github.com/BoundaryML/baml/blob/bd85ce9dee1463ff04d27efd20531013a4ff46c1/engine/language_client_go/pkg/rawobjects_client_registry.go#L25-L60","documentation":"encodeClientRegistry serializes each client's options map into CFFI structures before crossing the FFI boundary to the BAML runtime. If serde.EncodeMapEntries fails on a client's options map, the failure is wrapped as \"encoding client options: %w\". This means one of the values in the client options map is not encodable (unsupported type, nil where a value is required, etc.), so the registry cannot be marshaled.","triggerScenarios":"Registering or encoding a client (e.g. in baml.ClientRegistry / b.SetClientRegistry) whose options map contains a value type the CFFI serializer cannot encode — nested non-primitive types, func values, or malformed entries.","commonSituations":"Passing arbitrary Go values as client options instead of the supported primitives (string/number/bool); typos in option keys leading to structurally wrong maps; embedding options read from JSON with unexpected value shapes.","solutions":["Inspect the wrapped inner error to find which option entry failed, then restrict client options to supported primitive types (string, int, float, bool).","Normalize options coming from JSON/config files with explicit decoding into a typed struct instead of map[string]any passthrough.","Remove or replace function/pointer/nested-struct option values with their serializable equivalents.","Log the full options map (fmt.Sprintf(\"%#v\")) before registering the client to spot the offending entry."],"exampleFix":"// before\nb.SetClientRegistry(registryWith(map[string]any{\"retries\": customRetryer{}, \"url\": nil}))\n// after\nb.SetClientRegistry(registryWith(map[string]any{\n    \"retries\": 3,          // supported primitive\n    \"url\":    \"https://example.com\",\n}))","handlingStrategy":"validation","validationCode":"func validateClientOptions(opts map[string]any) error {\n    for k, v := range opts {\n        switch v.(type) {\n        case string, int, int64, float64, bool, nil:\n            continue\n        default:\n            return fmt.Errorf(\"client option %q has unsupported type %T\", k, v)\n        }\n    }\n    return nil\n}","typeGuard":"func isEncodableOption(v any) bool {\n    switch v.(type) {\n    case string, int, int64, float64, bool, nil:\n        return true\n    }\n    return false\n}","tryCatchPattern":"if err := validateClientOptions(clientOptions); err != nil {\n    return fmt.Errorf(\"rejecting client before registration: %w\", err)\n}\n// then register; wrap any residual error:\nif err := registerClient(clientOptions); err != nil {\n    return fmt.Errorf(\"client registration failed: %w\", err)\n}","preventionTips":["Restrict client options to JSON-compatible primitives","Decode JSON config into typed structs instead of map[string]any passthrough","Validate options maps at config-load time, before any registry encoding","Log %#v of the options map when encoding fails to spot the offending entry"],"tags":["go","serialization","cffi","config"],"backgroundTag":"json-marshal-failed","analyzedSha":"bd85ce9dee1463ff04d27efd20531013a4ff46c1","analyzedAt":"2026-09-12T03:38:25.718Z","contentChangedAt":"2026-09-12T03:38:25.718Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}