pion/webrtc · error
%w: invalid family 2 mapping
Error message
%w: invalid family 2 mapping
What it means
Channel mapping family 2 (non-diegetic channels, per the Opus spec) has exactly one legal configuration: one stream, zero coupled streams, and a single mapping entry of 0. validateFamilySpecificChannelMapping rejects any deviation from that exact tuple. The error wraps errInvalidChannelMap.
Source
Thrown at pkg/media/oggwriter/oggwriter.go:686
return fmt.Errorf("%w: channel map entry is out of range", errInvalidChannelMap)
}
}
return nil
}
func validateFamilySpecificChannelMapping(
family uint8,
streamCount uint8,
coupledCount uint8,
mapping []byte,
) error {
switch family {
case channelMappingFamily1:
return validateVorbisChannelMapping(streamCount, coupledCount, mapping)
case channelMappingFamily2:
if len(mapping) != 1 || streamCount != 1 || coupledCount != 0 || mapping[0] != 0 {
return fmt.Errorf("%w: invalid family 2 mapping", errInvalidChannelMap)
}
}
return nil
}
func validateVorbisChannelMapping(streamCount, coupledCount uint8, mapping []byte) error {
var wantStreams, wantCoupled uint8
var wantMapping []byte
switch len(mapping) {
case 1:
wantStreams = 1
wantCoupled = 0
wantMapping = []byte{0}
case 2:
wantStreams = 1
wantCoupled = 1
wantMapping = []byte{0, 1}View on GitHub (pinned to 8c25dc09fa)
Solutions
- If you meant stereo, use family 0 with streamCount=1, coupledCount=1, mapping {0,1}.
- For family 2, send exactly: streamCount=1, coupledCount=0, mapping=[]byte{0}.
- Drop the custom mapping and let defaultChannelMapping configure mono/stereo.
- Compare with errors.Is(err, errInvalidChannelMap) to identify mapping misconfigurations.
Example fix
// before
validateChannelMapping(channelMappingFamily2, 1, 1, []byte{0, 1})
// after
validateChannelMapping(channelMappingFamily2, 1, 0, []byte{0}) Defensive patterns
Strategy: validation
Validate before calling
func validFamily2(streams, coupled uint8, mapping []byte) bool {
return len(mapping) == 1 && streams == 1 && coupled == 0 && mapping[0] == 0
} Type guard
func isFamily2Compliant(m ChannelMapping) bool {
return m.Family == 2 && m.StreamCount == 1 && m.CoupledCount == 0 && len(m.Mapping) == 1 && m.Mapping[0] == 0
} Try / catch
if err := writer.AddOpusTrack(cfg); err != nil {
if errors.Is(err, errInvalidChannelMap) { /* family 2 requires 1/0/{0} */ }
return err
} Prevention
- Family 2 only allows the exact tuple (streams=1, coupled=0, mapping={0})
- Use family 0 for ordinary mono/stereo instead
- Don't reuse family-1 tables when switching family constants
- Verify family constants against the Opus spec before use
When it happens
Trigger: Passing family=channelMappingFamily2 with any of: len(mapping) != 1, streamCount != 1, coupledCount != 0, or mapping[0] != 0 — e.g. family 2 with a stereo mapping table.
Common situations: Choosing family 2 because it sounds like 'stereo/surround' when family 0 or 1 was intended; carrying over a family-1 mapping table while switching the family constant.
Related errors
- %w: stream count must be one
- %w: coupled count exceeds stream count
- %w: channel map entry is out of range
- %w: unsupported family 1 channel count
- %w: invalid family 1 mapping
AI-assisted analysis of pion/webrtc@8c25dc09fa (2026-09-03).
Data as JSON: /api/errors/c767d6e6a8e35dbe.
Report an issue: GitHub.