{"record":{"id":"8d79f1688cc9baf8","repo":"BoundaryML/baml","slug":"error-decoding-value-unknown-field-type","errorCode":null,"errorMessage":"error decoding value, unknown field type: ","messagePattern":"error decoding value, unknown field type: ","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"engine/language_client_go/baml_go/serde/decode.go","lineNumber":476,"sourceCode":"\t\tgoType, ok := typeMap.typeMap[namespace+\".\"+name]\n\t\tif !ok {\n\t\t\tpanic(\"error decoding value, type alias not found: \" + namespace + \".\" + name)\n\t\t}\n\t\treturn goType\n\t}\n\n\t// any is weird in go, (alias for interface{})\n\tif _, ok := type_.(*cffi.CFFIFieldTypeHolder_NullType); ok {\n\t\tif _, ok := typeMap.typeMap[\"INTERNAL.nil\"]; ok {\n\t\t\treturn reflect.TypeOf((*interface{})(nil)).Elem()\n\t\t}\n\t\treturn reflect.TypeOf((*interface{})(nil))\n\t}\n\tif _, ok := type_.(*cffi.CFFIFieldTypeHolder_AnyType); ok {\n\t\treturn reflect.TypeOf((*interface{})(nil)).Elem()\n\t}\n\n\tpanic(\"error decoding value, unknown field type: \" + fmt.Sprintf(\"%+v\", fieldType))\n}\n\nfunc typeToString(fieldType *cffi.CFFIFieldTypeHolder) string {\n\tif fieldType == nil {\n\t\tpanic(\"error decoding value\")\n\t}\n\n\tif _, ok := fieldType.Type.(*cffi.CFFIFieldTypeHolder_StringType); ok {\n\t\treturn \"string\"\n\t}\n\tif _, ok := fieldType.Type.(*cffi.CFFIFieldTypeHolder_BoolType); ok {\n\t\treturn \"bool\"\n\t}\n\tif _, ok := fieldType.Type.(*cffi.CFFIFieldTypeHolder_IntType); ok {\n\t\treturn \"int\"\n\t}\n\tif _, ok := fieldType.Type.(*cffi.CFFIFieldTypeHolder_FloatType); ok {\n\t\treturn \"float\"","sourceCodeStart":458,"sourceCodeEnd":494,"githubUrl":"https://github.com/BoundaryML/baml/blob/bd85ce9dee1463ff04d27efd20531013a4ff46c1/engine/language_client_go/baml_go/serde/decode.go#L458-L494","documentation":"This is the fallthrough at the end of convertFieldTypeToGoType: the decoder received a CFFIFieldTypeHolder whose variant is not any type it knows how to map to Go. Because the Go runtime and the Rust engine were compiled against different cffi enum definitions (or a nil type was passed), no branch matches and the library panics instead of returning a wrong type.","triggerScenarios":"The Rust baml engine (native lib) sends a field type variant unknown to the compiled Go runtime — e.g. using a newer engine/native lib with an older generated Go package — or a nil/invalid type descriptor reaches the converter through decodeListValue, decodeMapValue, or decodeUnionValue.","commonSituations":"Mixing baml versions: the native library updated by a package manager or build cache while the generated Go client was not; corrupted or hand-crafted cffi payloads in tests; engine features (new type variants) not yet supported by the installed Go client version.","solutions":["Upgrade or align the Go baml runtime and the generated client with the engine version (go get -u github.com/boundaryml/baml/... and regenerate)","Ensure the native baml library loaded at runtime matches the CLI version (clear stale caches, reinstall via the official installer)","Check the panic message's dumped fieldType (%+v) to identify the unknown variant, then upgrade to a Go client version that supports it","If it comes from a nested list/map/union element, isolate which BAML output type triggers it and simplify or pin versions until supported"],"exampleFix":"// before: go.mod pins old baml while native CLI is new\nrequire github.com/boundaryml/baml v0.65.0\n\n// after: align versions and regenerate\nrequire github.com/boundaryml/baml v0.75.0\n// baml-cli generate && go mod tidy && go build","handlingStrategy":"try-catch","validationCode":"// Startup self-check: pin and log versions\nfunc checkVersions() {\n\tlog.Printf(\"baml go runtime: %s, engine: %s\", baml_go.Version, baml.EngineVersion())\n\tif baml_go.Version != baml.EngineVersion() {\n\t\tlog.Printf(\"WARNING: engine/runtime version mismatch — regenerate client\")\n\t}\n}","typeGuard":null,"tryCatchPattern":"// Decode panics are not recoverable errors; recover at the RPC boundary\nfunc safeCall(fn func()) (recovered any) {\n\tdefer func() { recovered = recover() }()\n\tfn()\n\treturn nil\n}\n// usage: if r := safeCall(func(){ baml.MyFn(ctx, client, in) }); r != nil { log.Fatalf(\"baml decode panic: %v\", r) }","preventionTips":["Upgrade Go runtime, CLI, and native lib together; never partially","Clear stale native library caches when switching baml versions","Test decoding of every output type in CI after each baml upgrade"],"tags":["go","ffi","deserialization","version-mismatch","baml"],"backgroundTag":"unexpected-response-shape","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"}