{"record":{"id":"258bef6c0b85494d","repo":"hyperledger/fabric","slug":"err","errorCode":null,"errorMessage":"err","messagePattern":"err","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"protoutil/blockutils.go","lineNumber":215,"sourceCode":"\t\t\treturn 0, errors.Wrap(err, \"error unmarshalling LastConfig\")\n\t\t}\n\t\treturn lc.Index, nil\n\t}\n\n\tobm := &cb.OrdererBlockMetadata{}\n\terr = proto.Unmarshal(m.Value, obm)\n\tif err != nil {\n\t\treturn 0, errors.Wrap(err, \"failed to unmarshal orderer block metadata\")\n\t}\n\treturn obm.LastConfig.Index, nil\n}\n\n// GetLastConfigIndexFromBlockOrPanic retrieves the index of the last config\n// block as encoded in the block metadata, or panics on error\nfunc GetLastConfigIndexFromBlockOrPanic(block *cb.Block) uint64 {\n\tindex, err := GetLastConfigIndexFromBlock(block)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn index\n}\n\n// CopyBlockMetadata copies metadata from one block into another\nfunc CopyBlockMetadata(src *cb.Block, dst *cb.Block) {\n\tdst.Metadata = src.Metadata\n\t// Once copied initialize with rest of the\n\t// required metadata positions.\n\tInitBlockMetadata(dst)\n}\n\n// InitBlockMetadata initializes metadata structure\nfunc InitBlockMetadata(block *cb.Block) {\n\tif block.Metadata == nil {\n\t\tblock.Metadata = &cb.BlockMetadata{Metadata: [][]byte{{}, {}, {}, {}, {}}}\n\t} else if len(block.Metadata.Metadata) < int(cb.BlockMetadataIndex_COMMIT_HASH+1) {\n\t\tfor i := len(block.Metadata.Metadata); i <= int(cb.BlockMetadataIndex_COMMIT_HASH); i++ {","sourceCodeStart":197,"sourceCodeEnd":233,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/protoutil/blockutils.go#L197-L233","documentation":"GetLastConfigIndexFromBlockOrPanic is a convenience wrapper that calls GetLastConfigIndexFromBlock and panics on any error. The bare message \"err\" is simply the underlying error (unmarshalling failure or missing metadata) propagated as a panic. It indicates the block's last-config metadata could not be parsed or is absent.","triggerScenarios":"Calling GetLastConfigIndexFromBlockOrPanic with a block whose ORDERER/LAST_CONFIG metadata is missing, empty, or fails to unmarshal as LastConfig/OrdererBlockMetadata — e.g. a non-orderer block or corrupt data.","commonSituations":"Test code or chaincode/orderer paths passing a synthesized block without metadata, passing a block from a wrong channel type, or corrupt ledger data reaching a code path that assumes validity.","solutions":["Fix the caller to pass a real, valid block (with populated Metadata entries)","Switch to the non-panicking GetLastConfigIndexFromBlock and handle the error explicitly in production paths","Validate block.Metadata length (>= LAST_CONFIG index+1) before calling","Re-fetch the block from the ledger if its data is corrupt"],"exampleFix":"// before\nindex, err := GetLastConfigIndexFromBlock(block)\nif err != nil {\n    panic(err)\n}\n// after (caller side)\nindex, err := GetLastConfigIndexFromBlock(block)\nif err != nil {\n    return fmt.Errorf(\"block %d has no readable last-config metadata: %w\", block.GetHeader().GetNumber(), err)\n}","handlingStrategy":"type-guard","validationCode":"func safeLastConfigIndex(block *cb.Block) (uint64, error) {\n    if block == nil || block.GetMetadata() == nil {\n        return 0, errors.New(\"block has no metadata\")\n    }\n    return GetLastConfigIndexFromBlock(block)\n}","typeGuard":"func hasReadableLastConfig(block *cb.Block) bool {\n    _, err := GetLastConfigIndexFromBlock(block)\n    return err == nil\n}","tryCatchPattern":"defer func() {\n    if r := recover(); r != nil {\n        logger.Errorf(\"GetLastConfigIndexFromBlockOrPanic failed: %v\", r)\n    }\n}()","preventionTips":["Avoid the OrPanic wrapper outside of tests; prefer GetLastConfigIndexFromBlock","Validate block.Metadata is populated before calling","Only call on blocks known to come from the ordering service","Wrap calls in recover() when panicking paths are unavoidable"],"tags":["panic","last-config","block-metadata","invalid-input"],"backgroundTag":"invalid-block-metadata","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"}