BoundaryML/baml · error

error decoding value:

Error message

error decoding value: 

What it means

Decode's default branch: the CFFIValueHolder carried a Value variant that the Go serde switch does not recognize at all (not null/string/int/float/bool/class/enum/list/map/union/checked/streaming/literal/object). The Go runtime was compiled against a different CFFI protocol version than the engine, so it panics with the holder dump.

Source

Thrown at engine/language_client_go/baml_go/serde/decode.go:595

		return decodeClassValue(value.ClassValue, typeMap)
	case *cffi.CFFIValueHolder_EnumValue:
		return decodeEnumValue(value.EnumValue, typeMap)
	case *cffi.CFFIValueHolder_ListValue:
		return decodeListValue(value.ListValue, typeMap)
	case *cffi.CFFIValueHolder_MapValue:
		return decodeMapValue(value.MapValue, typeMap)
	case *cffi.CFFIValueHolder_UnionVariantValue:
		return decodeUnionValue(value.UnionVariantValue, typeMap)
	case *cffi.CFFIValueHolder_CheckedValue:
		return decodeCheckedValue(value.CheckedValue, typeMap)
	case *cffi.CFFIValueHolder_StreamingStateValue:
		return decodeStreamingStateValue(value.StreamingStateValue, typeMap)
	case *cffi.CFFIValueHolder_LiteralValue:
		return decodeLiteralValue(value.LiteralValue, typeMap)
	case *cffi.CFFIValueHolder_ObjectValue:
		panic("ObjectValue is not yet supported: " + holder.String())
	default:
		panic("error decoding value: " + holder.String())
	}
}

func decodeLiteralValue(valueLiteral *cffi.CFFIFieldTypeLiteral, _ TypeMap) (reflect.Value, reflect.Type) {
	if valueLiteral == nil {
		panic("decodeLiteralValue: valueLiteral is nil")
	}

	switch value := valueLiteral.Literal.(type) {
	case *cffi.CFFIFieldTypeLiteral_BoolLiteral:
		return reflect.ValueOf(value.BoolLiteral.Value), reflect.TypeOf(false)
	case *cffi.CFFIFieldTypeLiteral_IntLiteral:
		return reflect.ValueOf(value.IntLiteral.Value), reflect.TypeOf(int64(0))
	case *cffi.CFFIFieldTypeLiteral_StringLiteral:
		return reflect.ValueOf(value.StringLiteral.Value), reflect.TypeOf("")
	default:
		panic("error decoding value, unknown literal type: " + fmt.Sprintf("%+v", value))
	}

View on GitHub (pinned to bd85ce9dee)

Solutions

  1. Align versions: upgrade the Go baml runtime and regenerate so the Decode switch covers the engine's value variants
  2. Ensure the loaded native baml library matches the Go module version (reinstall the CLI/native lib)
  3. Inspect holder.String() in the panic to identify the unknown variant and cross-check baml release notes
  4. If intentional protocol extension, report/get a Go runtime fix; otherwise pin both sides to the same release

Example fix

// before: mixed versions -> unknown holder variant panic
// after:
go get github.com/boundaryml/baml@latest
baml-cli generate
go mod tidy && go build ./...
Defensive patterns

Strategy: try-catch

Validate before calling

// Fail fast on engine/runtime mismatch at startup
func init() {
	if baml.EngineVersion() != baml_go.GeneratedForVersion {
		panic("baml engine/runtime version mismatch — regenerate the Go client")
	}
}

Try / catch

defer func() {
	if r := recover(); r != nil {
		log.Printf("baml decode panic (unknown value holder): %v", r)
	}
}()

Prevention

When it happens

Trigger: The native baml library emits a value holder variant unknown to the compiled Go client — typical when the engine and Go dependency versions are out of sync, or when a malformed holder reaches Decode from the FFI layer.

Common situations: Partial upgrades (CLI updated, Go module not); vendored generated code drifting from the runtime; running against a dev build of the baml engine.

Related errors


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