BoundaryML/baml · error

encoding env vars: %w

Error message

encoding env vars: %w

What it means

Environment variables passed in BamlFunctionArguments.Env are converted to CFFI HostEnvVar entries with serde.EncodeEnvVar. This error wraps any failure from that conversion, meaning one of the env vars (key or value) could not be represented in the FFI payload.

Source

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

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)
			if err != nil {
				return nil, fmt.Errorf("encoding collector: %w", err)
			}
			collectors = append(collectors, encodedCollector)
		}
	}

	var typeBuilder *cffi.BamlObjectHandle

View on GitHub (pinned to bd85ce9dee)

Solutions

  1. Pass env vars as a map[string]string (all string keys and values)
  2. Convert non-string values with fmt.Sprintf/strconv before adding them to the env map
  3. Skip nil or empty entries instead of including them in the map
  4. Let the runtime inherit os.Environ() instead of hand-building the env map

Example fix

// before
env := map[string]any{"TIMEOUT": 30}
res, _ := runtime.CallFunction(ctx, "Fn", params, kwargs, env)
// after
env := map[string]string{"TIMEOUT": "30"}
res, _ := runtime.CallFunction(ctx, "Fn", params, kwargs, env)
Defensive patterns

Strategy: validation

Validate before calling

func validEnv(env map[string]string) bool {
    for k, v := range env { if k == "" { return false } ; _ = v }
    return true
}

Type guard

func asStringMap(v any) (map[string]string, bool) { m, ok := v.(map[string]string); return m, ok }

Try / catch

res, err := runtime.CallFunction(ctx, "Fn", params, kwargs, env)
if err != nil && strings.Contains(err.Error(), "encoding env vars") {
    return fmt.Errorf("env map must be map[string]string: %w", err)
}

Prevention

When it happens

Trigger: Calling a BAML function while passing an Env map containing keys or values that fail serde encoding — e.g. non-string values in the env map, or a nil/incorrectly-typed Env value.

Common situations: Passing a map[string]any env map where some values are nil or non-strings (ints, bools) instead of map[string]string; injecting process environment with unusual entries; custom env built for client credential overrides.

Understand the failure class

Background: "is not a valid" / "Invalid ... value" environment variable errors: how libraries validate env vars and what to do when they reject yours — this error's family across 48 libraries.

Related errors


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