{"record":{"id":"176d6b5cc50d0cf1","repo":"hyperledger/fabric","slug":"create-new-lock-based-txmgr-failed-passed-in-nil","errorCode":null,"errorMessage":"create new lock based TxMgr failed: passed in nil ledger hasher","messagePattern":"create new lock based TxMgr failed: passed in nil ledger hasher","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/ledger/kvledger/txmgmt/txmgr/lockbased_txmgr.go","lineNumber":97,"sourceCode":"\t}\n}\n\n// Initializer captures the dependencies for tx manager\ntype Initializer struct {\n\tLedgerID            string\n\tDB                  *privacyenabledstate.DB\n\tStateListeners      []ledger.StateListener\n\tBtlPolicy           pvtdatapolicy.BTLPolicy\n\tBookkeepingProvider *bookkeeping.Provider\n\tCCInfoProvider      ledger.DeployedChaincodeInfoProvider\n\tCustomTxProcessors  map[common.HeaderType]ledger.CustomTxProcessor\n\tHashFunc            rwsetutil.HashFunc\n}\n\n// NewLockBasedTxMgr constructs a new instance of NewLockBasedTxMgr\nfunc NewLockBasedTxMgr(initializer *Initializer) (*LockBasedTxMgr, error) {\n\tif initializer.HashFunc == nil {\n\t\treturn nil, errors.New(\"create new lock based TxMgr failed: passed in nil ledger hasher\")\n\t}\n\n\tif err := initializer.DB.Open(); err != nil {\n\t\treturn nil, err\n\t}\n\ttxmgr := &LockBasedTxMgr{\n\t\tledgerid:       initializer.LedgerID,\n\t\tdb:             initializer.DB,\n\t\tstateListeners: initializer.StateListeners,\n\t\tccInfoProvider: initializer.CCInfoProvider,\n\t\thashFunc:       initializer.HashFunc,\n\t}\n\tpvtstatePurgeMgr, err := pvtstatepurgemgmt.InstantiatePurgeMgr(\n\t\tinitializer.LedgerID,\n\t\tinitializer.DB,\n\t\tinitializer.BtlPolicy,\n\t\tinitializer.BookkeepingProvider,\n\t)","sourceCodeStart":79,"sourceCodeEnd":115,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/core/ledger/kvledger/txmgmt/txmgr/lockbased_txmgr.go#L79-L115","documentation":"NewLockBasedTxMgr requires a hash function from the ledger initializer to compute hashes for private-data and rwset handling. A nil HashFunc means the transaction manager cannot be constructed safely, so it fails fast.","triggerScenarios":"Calling NewLockBasedTxMgr with an Initializer whose HashFunc field is nil — typically in test harness setup (newTestHistoryEnv, initTxMgr) or custom ledger initializer code that omits the hasher.","commonSituations":"Test environments constructed without wiring a ledger hasher; refactoring where the Initializer struct gained the HashFunc field but existing setup code was not updated; custom peer extensions building their own Initializer.","solutions":["Provide a hash function in the Initializer, e.g. HashFunc: func(data []byte) ([]byte, error) { h := sha256.New(); h.Write(data); return h.Sum(nil), nil }.","Use the peer's standard ledger initializer (ledgerUtil) which wires the hasher automatically.","Update stale test harnesses to set HashFunc when constructing txmgmt.Initializer.","If HashFunc became required in a version upgrade, port the setup code to the new Initializer contract."],"exampleFix":"// before\ninitializer := &txmgr.Initializer{DB: db}\ntxmgr, err := txmgr.NewLockBasedTxMgr(initializer)\n// after\ninitializer := &txmgr.Initializer{\n  DB: db,\n  HashFunc: func(data []byte) ([]byte, error) {\n    h := sha256.New(); h.Write(data); return h.Sum(nil), nil\n  },\n}\ntxmgr, err := txmgr.NewLockBasedTxMgr(initializer)","handlingStrategy":"validation","validationCode":"if initializer == nil || initializer.HashFunc == nil {\n  return nil, errors.New(\"txmgr initializer requires a HashFunc\")\n}\ntxmgr, err := txmgr.NewLockBasedTxMgr(initializer)","typeGuard":"func initializerReady(i *txmgr.Initializer) bool {\n  return i != nil && i.HashFunc != nil && i.DB != nil\n}","tryCatchPattern":"txmgr, err := txmgr.NewLockBasedTxMgr(initializer)\nif err != nil {\n  return fmt.Errorf(\"tx manager init failed: %w\", err)\n}","preventionTips":["When constructing txmgmt.Initializer in tests, always set HashFunc alongside DB","Use the platform's standard ledger initializer rather than hand-building one","After version upgrades, update test harnesses for new Initializer fields"],"tags":["txmgr","initialization","missing-configuration","ledger"],"backgroundTag":"missing-required-config","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"}