pion/webrtc · error
%w: invalid family 1 mapping
Error message
%w: invalid family 1 mapping
What it means
For mapping family 1, once the mapping length (1 or 2) is recognized, the stream count, coupled count, and mapping bytes must exactly match the canonical Vorbis mono ({0}: 1/0) or stereo ({0,1}: 1/1) tables. Any other combination returns this error, wrapped around errInvalidChannelMap.
Source
Thrown at pkg/media/oggwriter/oggwriter.go:709
}
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}
default:
return fmt.Errorf("%w: unsupported family 1 channel count", errInvalidChannelMap)
}
if streamCount != wantStreams || coupledCount != wantCoupled || !bytes.Equal(mapping, wantMapping) {
return fmt.Errorf("%w: invalid family 1 mapping", errInvalidChannelMap)
}
return nil
}
func cloneChannelMapping(mapping channelMapping) channelMapping {
mapping.mapping = append([]byte(nil), mapping.mapping...)
return mapping
}
func defaultOpusTags() OpusTags {
return OpusTags{Vendor: defaultVendor}
}
func cloneOpusTags(opusTags OpusTags) OpusTags {
opusTags.UserComments = cloneUserComments(opusTags.UserComments)
View on GitHub (pinned to 8c25dc09fa)
Solutions
- Use the exact canonical tables: mono -> streams=1, coupled=0, {0}; stereo -> streams=1, coupled=1, {0,1}.
- Compare your table with bytes.Equal against the canonical mapping to spot ordering issues.
- Prefer defaultChannelMapping(channelCount) instead of a custom family-1 mapping.
- Handle via errors.Is(err, errInvalidChannelMap) in caller diagnostics.
Example fix
// before
validateChannelMapping(channelMappingFamily1, 1, 0, []byte{0, 1}) // mono counts, stereo table
// after
validateChannelMapping(channelMappingFamily1, 1, 1, []byte{0, 1}) Defensive patterns
Strategy: validation
Validate before calling
var canonical = map[int]struct{ s, c uint8; m []byte }{
1: {1, 0, []byte{0}},
2: {1, 1, []byte{0, 1}},
}
func matchesCanonical(n int, s, c uint8, m []byte) bool {
w, ok := canonical[n]; return ok && s == w.s && c == w.c && bytes.Equal(m, w.m)
} Type guard
func isCanonicalFamily1(s, c uint8, m []byte) bool {
if len(m) == 1 { return s == 1 && c == 0 && m[0] == 0 }
if len(m) == 2 { return s == 1 && c == 1 && m[0] == 0 && m[1] == 1 }
return false
} Try / catch
if err := validateChannelMapping(family, s, c, m); err != nil {
if errors.Is(err, errInvalidChannelMap) { /* compare against canonical {0}/{0,1} tables */ }
return err
} Prevention
- Use bytes.Equal against {0} or {0,1} rather than hand-writing tables
- Set counts to match the table: mono 1/0, stereo 1/1
- Don't reorder mapping entries for channel swapping at write time
- Prefer defaultChannelMapping(channelCount)
When it happens
Trigger: Passing family=channelMappingFamily1 with len(mapping)==1 or 2 but inconsistent streamCount/coupledCount/mapping bytes, e.g. streamCount=1, coupledCount=0, mapping []byte{0,1}, or mapping []byte{1,0}.
Common situations: Swapping coupledCount with the number of channels; reordering the mapping entries (e.g. channel-swap tables); typos when hand-rolling the mapping instead of using defaults.
Related errors
- %w: stream count must be one
- %w: coupled count exceeds stream count
- %w: channel map entry is out of range
- %w: invalid family 2 mapping
- %w: unsupported family 1 channel count
AI-assisted analysis of pion/webrtc@8c25dc09fa (2026-09-03).
Data as JSON: /api/errors/60f802af7588babd.
Report an issue: GitHub.