BoundaryML/baml · error
encoding client options: %w
Error message
encoding client options: %w
What it means
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.
Source
Thrown at engine/language_client_go/pkg/rawobjects_client_registry.go:43
c.clients = make(clientRegistryMap)
}
c.clients[name] = clientProperty{
provider: provider,
options: options,
}
}
func (c *ClientRegistry) SetPrimaryClient(name string) {
c.primary = &name
}
func encodeClientRegistry(clientRegistryVal *ClientRegistry) (*cffi.HostClientRegistry, error) {
clientOffsets := make([]*cffi.HostClientProperty, 0, len(clientRegistryVal.clients))
for name, client := range clientRegistryVal.clients {
options, err := serde.EncodeMapEntries(client.options, "client options")
if err != nil {
return nil, fmt.Errorf("encoding client options: %w", err)
}
clientOffsets = append(clientOffsets, &cffi.HostClientProperty{
Name: name,
Provider: client.provider,
RetryPolicy: client.retryPolicy,
Options: options,
})
}
clients := cffi.HostClientRegistry{
Clients: clientOffsets,
Primary: clientRegistryVal.primary,
}
return &clients, nil
}
View on GitHub (pinned to bd85ce9dee)
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.
Example fix
// before
b.SetClientRegistry(registryWith(map[string]any{"retries": customRetryer{}, "url": nil}))
// after
b.SetClientRegistry(registryWith(map[string]any{
"retries": 3, // supported primitive
"url": "https://example.com",
})) Defensive patterns
Strategy: validation
Validate before calling
func validateClientOptions(opts map[string]any) error {
for k, v := range opts {
switch v.(type) {
case string, int, int64, float64, bool, nil:
continue
default:
return fmt.Errorf("client option %q has unsupported type %T", k, v)
}
}
return nil
} Type guard
func isEncodableOption(v any) bool {
switch v.(type) {
case string, int, int64, float64, bool, nil:
return true
}
return false
} Try / catch
if err := validateClientOptions(clientOptions); err != nil {
return fmt.Errorf("rejecting client before registration: %w", err)
}
// then register; wrap any residual error:
if err := registerClient(clientOptions); err != nil {
return fmt.Errorf("client registration failed: %w", err)
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: json.Marshal / "failed to marshal" errors in Go: why "unsupported type" happens and how to fix it — this error's family across 22 libraries.
Related errors
- failed to marshal object constructor arguments: %w
- encoding method arguments: %w
- encoding internal object: %w
- encoding list: %w
- map key type must be string, got %s
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/52e9f45610d3e8a3.
Report an issue: GitHub.