{"record":{"id":"4b020b9ca0e6cc3f","repo":"hyperledger/fabric","slug":"configgroup-not-found-at-group-path-s","errorCode":null,"errorMessage":"ConfigGroup not found at group path: %s","messagePattern":"ConfigGroup not found at group path: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"common/configtx/configmap.go","lineNumber":120,"sourceCode":"\n// configMapToConfig is intended to be called from outside this file\n// It takes a configMap and converts it back into a *cb.ConfigGroup structure\nfunc configMapToConfig(configMap map[string]comparable, rootGroupKey string) (*cb.ConfigGroup, error) {\n\trootPath := pathSeparator + rootGroupKey\n\treturn recurseConfigMap(rootPath, configMap)\n}\n\n// recurseConfigMap is used only internally by configMapToConfig\n// Note, this function no longer mutates the cb.Config* entries within configMap\nfunc recurseConfigMap(path string, configMap map[string]comparable) (*cb.ConfigGroup, error) {\n\tgroupPath := groupPrefix + path\n\tgroup, ok := configMap[groupPath]\n\tif !ok {\n\t\treturn nil, errors.Errorf(\"missing group at path: %s\", groupPath)\n\t}\n\n\tif group.ConfigGroup == nil {\n\t\treturn nil, errors.Errorf(\"ConfigGroup not found at group path: %s\", groupPath)\n\t}\n\n\tnewConfigGroup := protoutil.NewConfigGroup()\n\tproto.Merge(newConfigGroup, group.ConfigGroup)\n\n\tfor key := range group.Groups {\n\t\tupdatedGroup, err := recurseConfigMap(path+pathSeparator+key, configMap)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tnewConfigGroup.Groups[key] = updatedGroup\n\t}\n\n\tfor key := range group.Values {\n\t\tvaluePath := valuePrefix + path + pathSeparator + key\n\t\tvalue, ok := configMap[valuePath]\n\t\tif !ok {\n\t\t\treturn nil, errors.Errorf(\"missing value at path: %s\", valuePath)","sourceCodeStart":102,"sourceCodeEnd":138,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/common/configtx/configmap.go#L102-L138","documentation":"recurseConfigMap found an entry at 'groups/<path>' in the configMap, but the entry does not wrap an actual cb.ConfigGroup (comparable.ConfigGroup is nil). The comparable type is a union of ConfigGroup/ConfigValue/ConfigPolicy, so this means the wrong kind of element was stored under a group path.","triggerScenarios":"recurseConfigMap encountering a configMap entry keyed as a group whose comparable has ConfigGroup == nil — e.g. a ConfigValue or ConfigPolicy stored under a 'groups/...' key, or a zero-value comparable inserted by buggy map construction.","commonSituations":"Hand-built maps with path/prefix confusion (groupPrefix vs valuePrefix); deserialization that left the ConfigGroup unset; tests seeding placeholder comparables without payloads.","solutions":["Fix the map construction so every 'groups/<path>' key holds comparable{ConfigGroup: ...}.","Regenerate the map with configtx.NewComparableConfig to guarantee path/prefix consistency.","Check constants groupPrefix/valuePrefix/policyPrefix usage if building keys manually — the prefix must match the payload kind.","Log the comparable at the reported path and correct the wrong kind stored there."],"exampleFix":"// before\nconfigMap[\"groups/Application\"] = comparable{ConfigValue: someValue}\n// after\nconfigMap[\"groups/Application\"] = comparable{ConfigGroup: appGroup}","handlingStrategy":"validation","validationCode":"func groupEntryIsGroup(configMap map[string]configtx.Comparable, path string) bool {\n\tc, ok := configMap[\"groups/\"+path]\n\treturn ok && c.ConfigGroup != nil\n}","typeGuard":"func asConfigGroup(c comparable) (*cb.ConfigGroup, bool) {\n\tif c.ConfigGroup == nil {\n\t\treturn nil, false\n\t}\n\treturn c.ConfigGroup, true\n}","tryCatchPattern":"// errors are returned, not panicked\nconfig, err := configtx.ConfigMapToConfig(configMap)\nif err != nil {\n\treturn fmt.Errorf(\"non-group payload under group path: %w\", err)\n}","preventionTips":["Match the comparable union member to the key prefix (groups/ -> ConfigGroup)","Let NewComparableConfig derive keys and payloads together","Add map invariants tests asserting kind/prefix consistency before conversion"],"tags":["hyperledger-fabric","configtx","config-map"],"backgroundTag":"missing-config-group-path","analyzedSha":"2736b63f8fd5932511d56fe68b7039d15977f7f6","analyzedAt":"2026-09-04T08:52:36.465Z","contentChangedAt":"2026-09-04T08:52:36.465Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}