{"record":{"id":"041e57835d15b62d","repo":"pion/webrtc","slug":"w-stream-count-must-be-one","errorCode":null,"errorMessage":"%w: stream count must be one","messagePattern":"%w: stream count must be one","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/media/oggwriter/oggwriter.go","lineNumber":659,"sourceCode":"\t\tmapping:      append([]byte(nil), mapping...),\n\t}, nil\n}\n\nfunc validateChannelMappingFamily(family uint8) error {\n\tswitch family {\n\tcase channelMappingFamily1, channelMappingFamily2, channelMappingFamily255:\n\t\treturn nil\n\tdefault:\n\t\treturn fmt.Errorf(\"%w: unsupported family %d\", errInvalidChannelMap, family)\n\t}\n}\n\nfunc validateChannelMappingLayout(streamCount, coupledCount uint8, mapping []byte) error {\n\tif len(mapping) == 0 || len(mapping) > math.MaxUint8 {\n\t\treturn errInvalidChannelCount\n\t}\n\tif streamCount != 1 {\n\t\treturn fmt.Errorf(\"%w: stream count must be one\", errInvalidChannelMap)\n\t}\n\tif coupledCount > streamCount {\n\t\treturn fmt.Errorf(\"%w: coupled count exceeds stream count\", errInvalidChannelMap)\n\t}\n\n\tdecodedChannels := int(streamCount) + int(coupledCount)\n\tfor _, channel := range mapping {\n\t\tif channel != math.MaxUint8 && int(channel) >= decodedChannels {\n\t\t\treturn fmt.Errorf(\"%w: channel map entry is out of range\", errInvalidChannelMap)\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc validateFamilySpecificChannelMapping(\n\tfamily uint8,\n\tstreamCount uint8,","sourceCodeStart":641,"sourceCodeEnd":677,"githubUrl":"https://github.com/pion/webrtc/blob/8c25dc09fa9e7c09aac4309ead88093d760432b0/pkg/media/oggwriter/oggwriter.go#L641-L677","documentation":"This error is returned by validateChannelMappingLayout when the channel mapping's streamCount is not exactly 1. The Ogg/Opus muxer in this library only supports single-stream (non-chained) Opus logical streams per track, so any channel mapping declaring more (or fewer) than one Opus stream is rejected before the identification header is written. It wraps errInvalidChannelMap so callers can errors.Is against it.","triggerScenarios":"Passing a channel mapping with streamCount != 1 to validateChannelMapping (e.g. via a custom channel-mapping option when adding an Opus track to an oggwriter), such as streamCount=2 with coupledCount=0 intended to encode two mono streams.","commonSituations":"Developers copying channel mapping tables from multi-stream Opus sources (e.g. surround-sound 5.1 encodes that use several Opus streams) or porting RTP depacketization code where multiple streams were supported; also happens when the stream/coupled counts are swapped with the mapping length.","solutions":["Set streamCount to 1 and encode all channels into that stream plus coupled streams (coupledCount <= streamCount).","Encode each extra logical stream as a separate track instead of one multi-stream track.","Keep the default mapping via defaultChannelMapping (mono: streamCount=1/coupled=0/family 0; stereo: streamCount=1/coupled=1/family 0) unless you specifically need a custom one.","Check errors.Is(err, errInvalidChannelMap) to distinguish mapping errors from other writer errors."],"exampleFix":"// before\nvalidateChannelMapping(family, 2, 1, []byte{0, 1, 2, 3}) // streamCount=2\n// after\nvalidateChannelMapping(family, 1, 1, []byte{0, 1, 2, 3}) // streamCount must be 1","handlingStrategy":"validation","validationCode":"func validStreamCount(streamCount uint8) bool { return streamCount == 1 }\nif !validStreamCount(cfg.StreamCount) { return fmt.Errorf(\"streamCount must be 1, got %d\", cfg.StreamCount) }","typeGuard":"func isSingleStreamMapping(m ChannelMapping) bool { return m.StreamCount == 1 }","tryCatchPattern":"if err := w.AddTrack(...); err != nil {\n    if errors.Is(err, errInvalidChannelMap) {\n        // fix channel mapping config before retrying\n    }\n    return err\n}","preventionTips":["Always set streamCount=1 for Opus tracks in this writer","Prefer defaultChannelMapping over hand-built mappings","Encode additional logical streams as separate tracks","Unit-test custom mappings with errors.Is(err, errInvalidChannelMap) checks"],"tags":["go","ogg","opus","channel-mapping","validation"],"backgroundTag":"invalid-opus-channel-mapping","analyzedSha":"8c25dc09fa9e7c09aac4309ead88093d760432b0","analyzedAt":"2026-09-03T21:56:56.182Z","contentChangedAt":"2026-09-03T21:56:56.182Z","schemaVersion":2},"datasetVersion":"2026-09-11T07:07:21.782Z"}