{"record":{"id":"a48c6e9047e84e95","repo":"hashicorp/nomad","slug":"prefix-q-unsupported-type-v","errorCode":null,"errorMessage":"prefix %q; unsupported type %v","messagePattern":"prefix %q; unsupported type (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"helper/flatmap/flatmap.go","lineNumber":110,"sourceCode":"\t\tif !e.IsValid() {\n\t\t\toutput[prefix] = \"nil\"\n\t\t\treturn\n\t\t}\n\t\tflatten(prefix, e, primitiveOnly, enteredStruct, output)\n\tcase reflect.Array, reflect.Slice:\n\t\tif primitiveOnly {\n\t\t\treturn\n\t\t}\n\n\t\tif v.Kind() == reflect.Slice && v.IsNil() {\n\t\t\toutput[prefix] = \"nil\"\n\t\t\treturn\n\t\t}\n\t\tfor i := 0; i < v.Len(); i++ {\n\t\t\tflatten(fmt.Sprintf(\"%s[%d]\", prefix, i), v.Index(i), primitiveOnly, enteredStruct, output)\n\t\t}\n\tdefault:\n\t\tpanic(fmt.Sprintf(\"prefix %q; unsupported type %v\", prefix, v.Kind()))\n\t}\n}\n\n// getSubPrefix takes the current prefix and the next subfield and returns an\n// appropriate prefix.\nfunc getSubPrefix(curPrefix, subField string) string {\n\tif curPrefix != \"\" {\n\t\treturn fmt.Sprintf(\"%s.%s\", curPrefix, subField)\n\t}\n\treturn subField\n}\n\n// getSubKeyPrefix takes the current prefix and the next subfield and returns an\n// appropriate prefix for a map field.\nfunc getSubKeyPrefix(curPrefix, subField string) string {\n\tif curPrefix != \"\" {\n\t\treturn fmt.Sprintf(\"%s[%s]\", curPrefix, subField)\n\t}","sourceCodeStart":92,"sourceCodeEnd":128,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/helper/flatmap/flatmap.go#L92-L128","documentation":"flatmap.flatten only supports maps, structs, slices/arrays, and primitives; any other reflect.Kind (e.g. chan, func, complex) hits the default branch and panics. It's an input-contract violation: the value being flattened must be composed of flatten-able types.","triggerScenarios":"Passing a value containing a func, channel, complex number, or unsafe pointer field to flatmap.Flatten / flatmap.Diff.","commonSituations":"Structs with embedded callback functions or channels passed into Nomad's diff/flatten utilities; job/task config values containing complex types that flatmap never accounted for; changes to upstream structs adding unsupported field types.","solutions":["Remove or exclude func/chan/complex fields from the struct before flattening","Convert unsupported fields to supported representations (string, numbers, maps, slices)","Nil out function/channel fields before calling Flatten"],"exampleFix":"// before\ntype Cfg struct{ Fn func() }\nflatmap.Flatten(Cfg{Fn: func(){}}) // panics\n// after\ntype Cfg struct{ Fn func() }\nc := Cfg{Fn: func(){}}\nc.Fn = nil // strip unsupported field\nflatmap.Flatten(c)","handlingStrategy":"validation","validationCode":"func flattenSupported(v reflect.Value) bool {\n    switch v.Kind() {\n    case reflect.Chan, reflect.Func, reflect.Complex64, reflect.Complex128, reflect.UnsafePointer:\n        return false\n    }\n    return true\n}\n","typeGuard":"func flattenSafe(v interface{}) (m map[string]string, ok bool) {\n    defer func() {\n        if r := recover(); r != nil { ok = false; m = nil }\n    }()\n    m = flatmap.Flatten(v)\n    return m, true\n}\n","tryCatchPattern":"defer func() {\n    if r := recover(); r != nil {\n        err = fmt.Errorf(\"flatmap unsupported type: %v\", r)\n    }\n}()","preventionTips":["Strip func/chan/complex fields from structs before flattening","Keep flatmap inputs to maps, slices, structs and primitives","Audit structs passed to Diff for newly added exotic fields"],"tags":["reflection","flatmap","panic","unsupported-type"],"backgroundTag":"flatmap-unsupported-type","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}