BoundaryML/baml · error

encoding client registry: %w

Error message

encoding client registry: %w

What it means

When BamlFunctionArguments carries a ClientRegistry, encode() converts it to the CFFI HostClientRegistry via encodeClientRegistry. Failure here means the registry's client definitions (name, provider, options) could not be serialized, and the error is wrapped with this prefix.

Source

Thrown at engine/language_client_go/pkg/rawobjects_function_args.go:39

func (args *BamlFunctionArguments) Encode() ([]byte, error) {
	encoded, err := args.encode()
	if err != nil {
		return nil, err
	}
	return proto.Marshal(encoded)
}

func (args *BamlFunctionArguments) encode() (*cffi.HostFunctionArguments, error) {
	kwargs, err := serde.EncodeMapEntries(args.Kwargs, "function arguments")
	if err != nil {
		return nil, fmt.Errorf("encoding function arguments: %w", err)
	}

	var clientRegistry *cffi.HostClientRegistry
	if args.ClientRegistry != nil {
		clientRegistry, err = encodeClientRegistry(args.ClientRegistry)
		if err != nil {
			return nil, fmt.Errorf("encoding client registry: %w", err)
		}
	}

	var env []*cffi.HostEnvVar
	if args.Env != nil {
		env, err = serde.EncodeEnvVar(args.Env)
		if err != nil {
			return nil, fmt.Errorf("encoding env vars: %w", err)
		}
	}

	var collectors []*cffi.BamlObjectHandle
	if args.Collectors != nil {
		for _, collector := range args.Collectors {
			if collector == nil {
				return nil, fmt.Errorf("nil collector found in collectors")
			}
			encodedCollector := raw_objects.EncodeRawObject(collector)

View on GitHub (pinned to bd85ce9dee)

Solutions

  1. Inspect each client in the registry: only primitive values (string, int, bool, float) in options maps
  2. Rebuild the ClientRegistry with baml.NewClientRegistry and NewClientBuilder instead of hand-rolling it
  3. Remove or fix the custom registry and fall back to the runtime's default clients from clients.baml
  4. Ensure registry client names match those referenced in the BAML functions

Example fix

// before
registry.Options()["retry"] = myCustomRetryPolicy{} // not encodable
// after
registry.Options()["retry"] = 3 // primitive value only
Defensive patterns

Strategy: validation

Validate before calling

func validRegistry(r *ClientRegistry) bool {
    if r == nil { return false }
    for _, o := range r.Options() {
        switch o.(type) {
        case string, int, int64, float64, bool, nil:
        default: return false
        }
    }
    return true
}

Try / catch

res, err := runtime.CallFunction(ctx, "Fn", params, kwargs, registry)
if err != nil && strings.Contains(err.Error(), "encoding client registry") {
    return fmt.Errorf("client registry options must be primitives: %w", err)
}

Prevention

When it happens

Trigger: Passing a ClientRegistry to CallFunction/SetBamlOptions where a client's options contain non-encodable values (e.g. wrong types in options map) or the registry itself was constructed inconsistently.

Common situations: Building a runtime client registry whose options map includes non-primitive values; typos in provider options that produce malformed entries; passing a registry from an incompatible runtime version.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12). Data as JSON: /api/errors/c4660fbf4b75ccc8. Report an issue: GitHub.