{"record":{"id":"2801234fb69a55f3","repo":"hyperledger/fabric","slug":"expected-version-s-does-not-match-passed-versio","errorCode":null,"errorMessage":"expected Version '%s' does not match passed Version '%s'","messagePattern":"expected Version '(.+?)' does not match passed Version '(.+?)'","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/chaincode/lifecycle/lifecycle.go","lineNumber":126,"sourceCode":"// or adding fields will cause opaque checks to fail.\ntype ChaincodeLocalPackage struct {\n\tPackageID string\n}\n\n// ChaincodeParameters are the parts of the chaincode definition which are serialized\n// as values in the statedb.  It is expected that any instance will have no nil fields once initialized.\n// WARNING: This structure is serialized/deserialized from the DB, re-ordering or adding fields\n// will cause opaque checks to fail.\ntype ChaincodeParameters struct {\n\tEndorsementInfo *lb.ChaincodeEndorsementInfo\n\tValidationInfo  *lb.ChaincodeValidationInfo\n\tCollections     *pb.CollectionConfigPackage\n}\n\nfunc (cp *ChaincodeParameters) Equal(ocp *ChaincodeParameters) error {\n\tswitch {\n\tcase cp.EndorsementInfo.Version != ocp.EndorsementInfo.Version:\n\t\treturn errors.Errorf(\"expected Version '%s' does not match passed Version '%s'\", cp.EndorsementInfo.Version, ocp.EndorsementInfo.Version)\n\tcase cp.EndorsementInfo.EndorsementPlugin != ocp.EndorsementInfo.EndorsementPlugin:\n\t\treturn errors.Errorf(\"expected EndorsementPlugin '%s' does not match passed EndorsementPlugin '%s'\", cp.EndorsementInfo.EndorsementPlugin, ocp.EndorsementInfo.EndorsementPlugin)\n\tcase cp.EndorsementInfo.InitRequired != ocp.EndorsementInfo.InitRequired:\n\t\treturn errors.Errorf(\"expected InitRequired '%t' does not match passed InitRequired '%t'\", cp.EndorsementInfo.InitRequired, ocp.EndorsementInfo.InitRequired)\n\tcase cp.ValidationInfo.ValidationPlugin != ocp.ValidationInfo.ValidationPlugin:\n\t\treturn errors.Errorf(\"expected ValidationPlugin '%s' does not match passed ValidationPlugin '%s'\", cp.ValidationInfo.ValidationPlugin, ocp.ValidationInfo.ValidationPlugin)\n\tcase !bytes.Equal(cp.ValidationInfo.ValidationParameter, ocp.ValidationInfo.ValidationParameter):\n\t\treturn errors.Errorf(\"expected ValidationParameter '%x' does not match passed ValidationParameter '%x'\", cp.ValidationInfo.ValidationParameter, ocp.ValidationInfo.ValidationParameter)\n\tcase !proto.Equal(cp.Collections, ocp.Collections):\n\t\treturn errors.Errorf(\"Collections do not match\")\n\tdefault:\n\t}\n\treturn nil\n}\n\n// ChaincodeDefinition contains the chaincode parameters, as well as the sequence number of the definition.\n// Note, it does not embed ChaincodeParameters so as not to complicate the serialization.  It is expected\n// that any instance will have no nil fields once initialized.","sourceCodeStart":108,"sourceCodeEnd":144,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/core/chaincode/lifecycle/lifecycle.go#L108-L144","documentation":"This error is thrown by ChaincodeParameters.Equal in the lifecycle package when comparing an existing (expected) chaincode definition against a newly passed one, and the EndorsementInfo.Version field differs. It exists so that an approval/commit attempt which redefines a chaincode with a different version than the already-committed definition is rejected with a precise field-level message.","triggerScenarios":"Calling CommitChaincodeDefinition or isAttemptToRedefine paths where the lifecycle ChaincodeParameters of the committed definition are compared via Equal and cp.EndorsementInfo.Version != ocp.EndorsementInfo.Version.","commonSituations":"Redeploying a chaincode with a bumped version while the same sequence number is already committed; peer state and approved definition out of sync; operator typos like 'v1.0' vs '1.0' when re-submitting a definition.","solutions":["Use the exact version string that matches the currently committed definition, or increment the sequence number when intentionally changing the version","Run 'peer lifecycle chaincode querycommitted' to see the committed version and align your approval with it","Re-approve with the correct version so approved and committed definitions match"],"exampleFix":"// before\nCommitChaincodeDefinition(name: 'mycc', version: '2.0', sequence: 1) // committed version is 1.0\n// after\nCommitChaincodeDefinition(name: 'mycc', version: '1.0', sequence: 1) // match committed version, or bump sequence to 2 for version 2.0","handlingStrategy":"validation","validationCode":"committed, err := lifecycle.QueryChaincodeDefinition(chname, ccname, publicState)\nif err == nil {\n    if newDef.EndorsementInfo.Version != committed.EndorsementInfo.Version && newDef.Sequence == committed.Sequence {\n        return fmt.Errorf(\"version %q differs from committed %q at same sequence\", newDef.EndorsementInfo.Version, committed.EndorsementInfo.Version)\n    }\n}","typeGuard":"func sameVersion(a, b *lifecycle.ChaincodeParameters) bool {\n    return a != nil && b != nil && a.EndorsementInfo.Version == b.EndorsementInfo.Version\n}","tryCatchPattern":"if err := params.Equal(committedParams); err != nil {\n    if strings.Contains(err.Error(), \"does not match passed Version\") {\n        // re-query committed definition and re-approve with correct version or sequence+1\n    }\n    return err\n}","preventionTips":["Always run querycommitted before approving/committing to read the current version and sequence","Keep version strings in a single source (CI variable) to avoid typos like v1.0 vs 1.0","Bump the sequence number every time you intentionally change any definition field"],"tags":["hyperledger-fabric","lifecycle","chaincode-definition","version-mismatch"],"backgroundTag":"chaincode-definition-mismatch","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"}