{"record":{"id":"68f2c0480ad3f4a1","repo":"hyperledger/fabric","slug":"error-only-a-single-deliver-source-is-currently","errorCode":null,"errorMessage":"ERROR - only a single deliver source is currently supported","messagePattern":"ERROR - only a single deliver source is currently supported","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/peer/channel/channel.go","lineNumber":136,"sourceCode":"\tGetOldestBlock() (*cb.Block, error)\n\tGetNewestBlock() (*cb.Block, error)\n\tClose() error\n}\n\n// ChannelCmdFactory holds the clients used by ChannelCmdFactory\ntype ChannelCmdFactory struct {\n\tEndorserClient   pb.EndorserClient\n\tSigner           msp.SigningIdentity\n\tBroadcastClient  common.BroadcastClient\n\tDeliverClient    deliverClientIntf\n\tBroadcastFactory BroadcastClientFactory\n}\n\n// InitCmdFactory init the ChannelCmdFactory with clients to endorser and orderer based on the given parameters\nfunc InitCmdFactory(isEndorserRequired, isPeerDeliverRequired, isOrdererRequired bool) (*ChannelCmdFactory, error) {\n\tif isPeerDeliverRequired && isOrdererRequired {\n\t\t// this is likely a bug during development caused by adding a new cmd\n\t\treturn nil, errors.New(\"ERROR - only a single deliver source is currently supported\")\n\t}\n\n\tvar err error\n\tcf := &ChannelCmdFactory{}\n\n\tcf.Signer, err = common.GetDefaultSignerFnc()\n\tif err != nil {\n\t\treturn nil, errors.WithMessage(err, \"error getting default signer\")\n\t}\n\n\tcf.BroadcastFactory = func() (common.BroadcastClient, error) {\n\t\treturn common.GetBroadcastClientFnc()\n\t}\n\n\t// for join and list, we need the endorser as well\n\tif isEndorserRequired {\n\t\t// creating an EndorserClient with these empty parameters will create a\n\t\t// connection using the values of \"peer.address\" and","sourceCodeStart":118,"sourceCodeEnd":154,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/internal/peer/channel/channel.go#L118-L154","documentation":"InitCmdFactory builds the client factory for peer channel commands. A command can take its block/deliver stream from either the peer's deliver service or the ordering service — never both. Receiving both flags true indicates a developer bug in wiring a new command, so it refuses to proceed.","triggerScenarios":"Calling InitCmdFactory with isPeerDeliverRequired=true AND isOrdererRequired=true — typically when adding or modifying a channel subcommand and passing the wrong boolean combination.","commonSituations":"Contributing a new `peer channel` subcommand; refactoring an existing command's deliver source; copying an InitCmdFactory call and flipping flags incorrectly.","solutions":["Fix the call site to pass exactly one deliver source: e.g. InitCmdFactory(EndorserRequired, PeerDeliverRequired, OrdererNotRequired) or (..., PeerDeliverNotRequired, OrdererRequired).","Review which service should serve blocks for your command: peer deliver for existing channels, orderer for channel creation.","Write a unit test asserting the flag combination for your command."],"exampleFix":"// before\nfactory, err := channel.InitCmdFactory(channel.EndorserRequired, channel.PeerDeliverRequired, channel.OrdererRequired)\n// after\nfactory, err := channel.InitCmdFactory(channel.EndorserRequired, channel.PeerDeliverRequired, channel.OrdererNotRequired)","handlingStrategy":"validation","validationCode":"// caller-side check when invoking InitCmdFactory\nif isPeerDeliverRequired && isOrdererRequired {\n    return nil, errors.New(\"choose exactly one deliver source: peer deliver OR orderer\")\n}","typeGuard":null,"tryCatchPattern":"cf, err := channel.InitCmdFactory(isEndorser, isPeerDeliver, isOrderer)\nif err != nil {\n    return fmt.Errorf(\"init channel factory: %w\", err)\n}","preventionTips":["Keep a table of flag combos per channel subcommand.","Add unit tests asserting InitCmdFactory rejects both-true combos.","Review any new channel command for exactly one deliver source."],"tags":["fabric","internal-bug","configuration"],"backgroundTag":"invalid-argument-combination","analyzedSha":"2736b63f8fd5932511d56fe68b7039d15977f7f6","analyzedAt":"2026-09-04T08:52:36.465Z","contentChangedAt":"2026-09-04T08:52:36.465Z","schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}