pion/webrtc · error

%w: coupled count exceeds stream count

Error message

%w: coupled count exceeds stream count

What it means

validateChannelMappingLayout returns this when coupledCount is greater than streamCount. In the Opus mapping family format, coupledCount is the number of stereo (coupled) streams and must not exceed the total number of streams; with streamCount fixed at 1 in this writer, only coupledCount of 0 or 1 is valid. The error wraps errInvalidChannelMap.

Source

Thrown at pkg/media/oggwriter/oggwriter.go:662

func validateChannelMappingFamily(family uint8) error {
	switch family {
	case channelMappingFamily1, channelMappingFamily2, channelMappingFamily255:
		return nil
	default:
		return fmt.Errorf("%w: unsupported family %d", errInvalidChannelMap, family)
	}
}

func validateChannelMappingLayout(streamCount, coupledCount uint8, mapping []byte) error {
	if len(mapping) == 0 || len(mapping) > math.MaxUint8 {
		return errInvalidChannelCount
	}
	if streamCount != 1 {
		return fmt.Errorf("%w: stream count must be one", errInvalidChannelMap)
	}
	if coupledCount > streamCount {
		return fmt.Errorf("%w: coupled count exceeds stream count", errInvalidChannelMap)
	}

	decodedChannels := int(streamCount) + int(coupledCount)
	for _, channel := range mapping {
		if channel != math.MaxUint8 && int(channel) >= decodedChannels {
			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 {

View on GitHub (pinned to 8c25dc09fa)

Solutions

  1. Ensure coupledCount <= streamCount, with streamCount=1 use coupledCount 0 (mono) or 1 (stereo).
  2. Remember coupledCount counts streams (each covering 2 channels), not individual channels.
  3. Use the library defaults from defaultChannelMapping for 1 or 2 channel audio.
  4. Guard with errors.Is(err, errInvalidChannelMap) for diagnostics.

Example fix

// before
validateChannelMapping(family, 1, 2, mapping) // coupled=2 > streams=1
// after
validateChannelMapping(family, 1, 1, mapping)
Defensive patterns

Strategy: validation

Validate before calling

func validCoupledCount(streams, coupled uint8) bool { return coupled <= streams }
if !validCoupledCount(cfg.StreamCount, cfg.CoupledCount) { return errors.New("coupled count exceeds stream count") }

Type guard

func isCoupledCountInRange(m ChannelMapping) bool { return m.CoupledCount <= m.StreamCount }

Try / catch

if err := writer.Configure(mapping); err != nil {
    if errors.Is(err, errInvalidChannelMap) { /* log mapping fields and fix counts */ }
    return err
}

Prevention

When it happens

Trigger: Calling the channel-mapping validation path with coupledCount > streamCount, e.g. streamCount=1 and coupledCount=2, or passing coupledCount=1 with streamCount=0.

Common situations: Misreading the Opus spec where coupled counts enumerate stereo decoders: developers set coupledCount equal to the number of coupled channels (2) instead of the number of coupled streams (1); also occurs when counts are accidentally swapped with each other or with channelCount.

Related errors


AI-assisted analysis of pion/webrtc@8c25dc09fa (2026-09-03). Data as JSON: /api/errors/09159ab82029129b. Report an issue: GitHub.