{"record":{"id":"0f66f46481906785","repo":"hyperledger/fabric","slug":"invalid-policy-name-during-channelless-check-polic-0f66f4","errorCode":null,"errorMessage":"invalid policy name during channelless check policy. Name must be different from nil.","messagePattern":"invalid policy name during channelless check policy\\. Name must be different from nil\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/policy/policy.go","lineNumber":193,"sourceCode":"\n\t// Recall that get policy always returns a policy object\n\tpolicy, _ := policyManager.GetPolicy(policyName)\n\n\t// Evaluate the policy\n\terr := policy.EvaluateSignedData(sd)\n\tif err != nil {\n\t\tlogger.Warnw(\"Failed evaluating policy on signed data\", \"error\", err, \"policyName\", policyName, \"identities\", protoutil.LogMessageForSerializedIdentities(sd))\n\t\treturn fmt.Errorf(\"Failed evaluating policy on signed data during check policy on channel [%s] with policy [%s]: [%s]\", channelID, policyName, err)\n\t}\n\n\treturn nil\n}\n\n// CheckPolicyNoChannelBySignedData checks that the passed signed data are valid with the respect to\n// passed policy on the local MSP.\nfunc (p *policyChecker) CheckPolicyNoChannelBySignedData(policyName string, signedData []*protoutil.SignedData) error {\n\tif policyName == \"\" {\n\t\treturn errors.New(\"invalid policy name during channelless check policy. Name must be different from nil.\")\n\t}\n\n\tif len(signedData) == 0 {\n\t\treturn fmt.Errorf(\"no signed data during channelless check policy with policy [%s]\", policyName)\n\t}\n\n\tfor _, data := range signedData {\n\t\t// Deserialize identity with the local MSP\n\t\tid, err := p.localMSP.DeserializeIdentity(data.Identity)\n\t\tif err != nil {\n\t\t\tlogger.Warnw(\"Failed deserializing signed data identity during channelless check policy\", \"error\", err, \"policyName\", policyName, \"identity\", protoutil.LogMessageForSerializedIdentity(data.Identity))\n\t\t\treturn fmt.Errorf(\"failed deserializing signed data identity during channelless check policy with policy [%s]: [%s]\", policyName, err)\n\t\t}\n\n\t\t// Load MSPPrincipal for policy\n\t\tprincipal, err := p.principalGetter.Get(policyName)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed getting local MSP principal during channelless check policy with policy [%s]: [%s]\", policyName, err)","sourceCodeStart":175,"sourceCodeEnd":211,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/core/policy/policy.go#L175-L211","documentation":"CheckPolicyNoChannelBySignedData rejects an empty policy name before doing any work, because a channelless policy check resolves the policy name to an MSPPrincipal on the local MSP; an empty name identifies no principal. The message's 'different from nil' is legacy Go phrasing for 'must not be empty'. It is a pure input-validation error, thrown synchronously at the first guard in the function.","triggerScenarios":"Calling CheckPolicyNoChannelBySignedData(\"\") with any signedData slice; typically a caller obtained policyName from an unset config value, an empty CLI flag, or a struct field that was never populated.","commonSituations":"System chaincode or CLI code passing a policy name sourced from configuration where the key is missing; callers that intended a channel-based check but routed through the channelless variant with default-empty variables; refactoring where a constant was accidentally removed.","solutions":["Pass a real local-MSP principal name, e.g. an MSP ID or a role-style principal string the MSPPrincipalGetter understands.","Check the config/flag source for the policy name and fail fast with your own clear error when empty.","If a channel-scoped check was intended, call CheckPolicyBySignedData with a non-empty channelID and a channel policy name (e.g. 'Writers') instead.","Add a guard in your caller: if policyName == \"\" { return errors.New(...) } before invoking the checker."],"exampleFix":"// before\nerr := policyChecker.CheckPolicyNoChannelBySignedData(policyName, sd) // policyName == \"\"\n// after\nif policyName == \"\" {\n    return errors.New(\"policy name must be configured for channelless policy check\")\n}\nerr := policyChecker.CheckPolicyNoChannelBySignedData(policyName, sd)","handlingStrategy":"validation","validationCode":"if policyName == \"\" {\n    return errors.New(\"policy name must be a non-empty MSP principal name for channelless check\")\n}\nerr := policyChecker.CheckPolicyNoChannelBySignedData(policyName, signedData)","typeGuard":"func hasPolicyName(policyName string) bool { return strings.TrimSpace(policyName) != \"\" }","tryCatchPattern":null,"preventionTips":["Fail fast on empty config values when loading policy names from configuration.","Distinguish channel-policy checks (CheckPolicy*) from channelless MSP-principal checks and never pass channel policy names to the latter.","Trim whitespace from externally supplied policy names before use.","Add unit tests covering the empty-name path."],"tags":["hyperledger-fabric","input-validation","empty-string","msp-principal"],"backgroundTag":"missing-or-empty-parameter","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"}