hyperledger/fabric · error

missing value at path: %s

Error message

missing value at path: %s

What it means

For each value declared in a group's Values map, recurseConfigMap requires a corresponding 'values/<path>/<key>' entry in the flattened configMap. This error means a value key exists in the group's Values metadata but its entry is missing from the map. Like the group-path errors, it signals an incomplete or inconsistently built configMap.

Source

Thrown at common/configtx/configmap.go:138

		return nil, errors.Errorf("ConfigGroup not found at group path: %s", groupPath)
	}

	newConfigGroup := protoutil.NewConfigGroup()
	proto.Merge(newConfigGroup, group.ConfigGroup)

	for key := range group.Groups {
		updatedGroup, err := recurseConfigMap(path+pathSeparator+key, configMap)
		if err != nil {
			return nil, err
		}
		newConfigGroup.Groups[key] = updatedGroup
	}

	for key := range group.Values {
		valuePath := valuePrefix + path + pathSeparator + key
		value, ok := configMap[valuePath]
		if !ok {
			return nil, errors.Errorf("missing value at path: %s", valuePath)
		}
		if value.ConfigValue == nil {
			return nil, errors.Errorf("ConfigValue not found at value path: %s", valuePath)
		}
		newConfigGroup.Values[key] = proto.Clone(value.ConfigValue).(*cb.ConfigValue)
	}

	for key := range group.Policies {
		policyPath := policyPrefix + path + pathSeparator + key
		policy, ok := configMap[policyPath]
		if !ok {
			return nil, errors.Errorf("missing policy at path: %s", policyPath)
		}
		if policy.ConfigPolicy == nil {
			return nil, errors.Errorf("ConfigPolicy not found at policy path: %s", policyPath)
		}
		newConfigGroup.Policies[key] = proto.Clone(policy.ConfigPolicy).(*cb.ConfigPolicy)
		logger.Debugf("Setting policy for key %s to %+v", key, group.Policies[key])

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Rebuild the configMap with configtx.NewComparableConfig(group) so every declared value has a map entry.
  2. Compare group.Values keys against the map's 'values/...' keys for the reported path and add the missing one.
  3. Ensure the root group passed to configMapToConfig matches the one the map was derived from.
  4. Remove concurrent writers or snapshot the map before conversion.

Example fix

// before
configMap["values/Consortium"] = comparable{ConfigValue: consortiumVal}
// group also declares BatchSize but map lacks values/Orderer/values/BatchSize
// after
configMap := NewComparableConfig(ordererGroup) // all values included
Defensive patterns

Strategy: validation

Validate before calling

func allValuesPresent(group *cb.ConfigGroup, configMap map[string]configtx.Comparable, path string) error {
	for key := range group.Values {
		if _, ok := configMap["values/"+path+"/"+key]; !ok {
			return fmt.Errorf("value %q missing at %s", key, path)
		}
	}
	return nil
}

Try / catch

// errors are returned, not panicked
config, err := configtx.ConfigMapToConfig(configMap)
if err != nil {
	return fmt.Errorf("value walk failed: %w", err)
}

Prevention

When it happens

Trigger: recurseConfigMap looking up valuePath = valuePrefix + path + '/' + key for every key in group.Values when the entry is absent — the group's Values map lists the value but the map builder skipped it.

Common situations: Partially copied/hand-built config maps; a map generated from a different (older/newer) group than the one being walked, so value keys diverge; concurrent modification removing entries mid-walk.

Related errors


AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04). Data as JSON: /api/errors/f114f2ac02cd005a. Report an issue: GitHub.