{"record":{"id":"330a3371fbb96ae5","repo":"BoundaryML/baml","slug":"unsupported-map-key-type-s","errorCode":null,"errorMessage":"unsupported map key type: %s","messagePattern":"unsupported map key type: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"engine/language_client_go/baml_go/serde/encode.go","lineNumber":241,"sourceCode":"\t\tswitch key.Kind() {\n\t\tcase reflect.String:\n\t\t\t// Go doesn't have enums, so we can't detect them here\n\t\t\tentries = append(entries, &cffi.HostMapEntry{\n\t\t\t\tKey:   &cffi.HostMapEntry_StringKey{StringKey: key.String()},\n\t\t\t\tValue: valueHolder,\n\t\t\t})\n\t\tcase reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:\n\t\t\tentries = append(entries, &cffi.HostMapEntry{\n\t\t\t\tKey:   &cffi.HostMapEntry_IntKey{IntKey: key.Int()},\n\t\t\t\tValue: valueHolder,\n\t\t\t})\n\t\tcase reflect.Bool:\n\t\t\tentries = append(entries, &cffi.HostMapEntry{\n\t\t\t\tKey:   &cffi.HostMapEntry_BoolKey{BoolKey: key.Bool()},\n\t\t\t\tValue: valueHolder,\n\t\t\t})\n\t\tdefault:\n\t\t\treturn nil, fmt.Errorf(\"unsupported map key type: %s\", key.Kind())\n\t\t}\n\t}\n\n\treturn &cffi.HostMapValue{\n\t\tEntries: entries,\n\t}, nil\n}\n\n// Helper function to encode map entries into a vector offset\nfunc EncodeMapEntries(fields map[string]any, context string) ([]*cffi.HostMapEntry, error) {\n\tentries := make([]*cffi.HostMapEntry, 0, len(fields))\n\t// Build entries (order doesn't strictly matter, but need to build bottom-up)\n\tfor k, v := range fields {\n\t\tkey := k\n\t\tvalueHolder, err := encodeValue(v)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"encoding %s field '%s': %w\", context, k, err)\n\t\t}","sourceCodeStart":223,"sourceCodeEnd":259,"githubUrl":"https://github.com/BoundaryML/baml/blob/bd85ce9dee1463ff04d27efd20531013a4ff46c1/engine/language_client_go/baml_go/serde/encode.go#L223-L259","documentation":"encodeMap serializes Go maps into the cffi HostMapValue sent across the FFI boundary to the BAML runtime. Go maps can be keyed by many primitive kinds, but only the kinds with a corresponding HostMapEntry_XXXKey variant (string, int, bool, etc.) are supported. When a map key's reflect.Kind has no encoder case, this error is returned so the whole encoding fails fast rather than silently dropping data.","triggerScenarios":"Passing a map with an unsupported key type (e.g. map[float64]T, map[struct{...}]T, map[chan T]T, map[*T]T, or a custom named type whose underlying kind is unsupported) into any API that encodes arguments — e.g. a BAML function parameter, client registry value, or context encoded via encodeValue -> encodeMap.","commonSituations":"Developers using float keys parsed from JSON, struct or pointer keys used as composite map keys, or time.Time / custom types as map keys. Also seen after refactoring a map[string]T into a map[SomeEnum]T where the enum is not a supported string-backed kind.","solutions":["Change the map key to a supported primitive: string, integer, or bool (e.g. map[string]T).","If keys are floats, convert them to formatted strings (strconv.FormatFloat) before encoding.","If keys are structs or pointers, derive a canonical string key (e.g. fmt.Sprintf or a serialized id) before passing to BAML.","If the key kind genuinely should be supported, file an issue / add a case to encodeMap in engine/language_client_go/baml_go/serde/encode.go."],"exampleFix":"// before\nm := map[float64]any{1.5: \"x\"}\nctx.Encode(m)\n\n// after\nm := map[string]any{}\nfor k, v := range rawFloatMap {\n    m[strconv.FormatFloat(k, 'f', -1, 64)] = v\n}\nctx.Encode(m)","handlingStrategy":"validation","validationCode":"func checkMapKeys(m any) error {\n\trv := reflect.ValueOf(m)\n\tif rv.Kind() != reflect.Map {\n\t\treturn fmt.Errorf(\"not a map\")\n\t}\n\tfor _, k := range rv.MapKeys() {\n\t\tswitch k.Kind() {\n\t\tcase reflect.String, reflect.Int, reflect.Int32, reflect.Int64, reflect.Bool:\n\t\tdefault:\n\t\t\treturn fmt.Errorf(\"unsupported map key kind: %s\", k.Kind())\n\t\t}\n\t}\n\treturn nil\n}","typeGuard":"func hasStringKeys(m any) bool {\n\trv := reflect.ValueOf(m)\n\treturn rv.Kind() == reflect.Map && rv.Type().Key().Kind() == reflect.String\n}","tryCatchPattern":"entries, err := serde.EncodeMapEntries(ctx, fields)\nif err != nil {\n\treturn fmt.Errorf(\"encoding args failed: %w\", err)\n}","preventionTips":["Use map[string]T for anything crossing the BAML FFI boundary","Avoid float, struct, and pointer map keys in BAML parameters","Convert complex keys to canonical strings before encoding"],"tags":["go","serialization","ffi","unsupported-type"],"backgroundTag":"unsupported-operation","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"}