{"record":{"id":"a0ef04154d1f44d4","repo":"hyperledger/fabric","slug":"signer-cannot-be-nil","errorCode":null,"errorMessage":"signer cannot be nil","messagePattern":"signer cannot be nil","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/peer/lifecycle/chaincode/common.go","lineNumber":54,"sourceCode":"// Signer defines the interface needed for signing messages\ntype Signer interface {\n\tSign(msg []byte) ([]byte, error)\n\tSerialize() ([]byte, error)\n}\n\n// Writer defines the interface needed for writing a file\ntype Writer interface {\n\tWriteFile(string, string, []byte) error\n}\n\nfunc signProposal(proposal *pb.Proposal, signer Signer) (*pb.SignedProposal, error) {\n\t// check for nil argument\n\tif proposal == nil {\n\t\treturn nil, errors.New(\"proposal cannot be nil\")\n\t}\n\n\tif signer == nil {\n\t\treturn nil, errors.New(\"signer cannot be nil\")\n\t}\n\n\tproposalBytes, err := proto.Marshal(proposal)\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, \"error marshaling proposal\")\n\t}\n\n\tsignature, err := signer.Sign(proposalBytes)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &pb.SignedProposal{\n\t\tProposalBytes: proposalBytes,\n\t\tSignature:     signature,\n\t}, nil\n}\n","sourceCodeStart":36,"sourceCodeEnd":72,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/internal/peer/lifecycle/chaincode/common.go#L36-L72","documentation":"signProposal requires a Signer (an identity whose private key signs the marshaled proposal bytes). It returns this error when the signer argument is nil. Without a signer the peer CLI cannot authenticate the lifecycle proposal to the endorser.","triggerScenarios":"Approve, ReadinessCheck, Commit, Get, Install, or Query invoke signProposal with a nil signer — i.e., no signing identity was obtained (e.g. signer retrieval failed but error was ignored, or msp-based signer construction returned nil).","commonSituations":"Running peer lifecycle commands without a properly configured local MSP (peer context missing core.yaml local mspadmincerts/keystore), or embedding the library without wiring a signing identity.","solutions":["Ensure the peer's local MSP is configured (FABRIC_CFG_PATH, mspConfigPath, local msp dirs with admincerts/signcerts/keystore)","Verify the signer lookup that precedes signProposal did not return (nil, nil) and ignore its error","Pass a valid Signer implementation when calling the library directly"],"exampleFix":"// before\nsp, err := signProposal(proposal, nil)\n// after\nsigner, err := localmsp.NewSigner()\nif err != nil {\n    return err\n}\nsp, err := signProposal(proposal, signer)","handlingStrategy":"validation","validationCode":"signer, err := localmsp.NewSigner()\nif err != nil {\n    return err\n}\nif signer == nil {\n    return errors.New(\"no signing identity configured\")\n}\nsp, err := signProposal(proposal, signer)","typeGuard":"func hasSigner(s Signer) bool { return s != nil }","tryCatchPattern":"if err != nil {\n    if strings.Contains(err.Error(), \"signer cannot be nil\") {\n        // verify local MSP configuration (FABRIC_CFG_PATH, mspConfigPath)\n    }\n}","preventionTips":["Configure the peer local MSP correctly before running lifecycle commands","Never ignore errors from signer-construction functions","In embedded use, inject a concrete Signer at startup and assert non-nil"],"tags":["fabric","lifecycle","signing","nil-argument"],"backgroundTag":"missing-signing-identity","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"}