pion/webrtc · error

output not opened

Error message

output not opened

What it means

errOutputNotOpened is returned by oggwriter.NewWriter when the provided io.Writer is nil, and by the internal stream-access path when w.stream is nil (e.g. writing before a valid output was attached). It indicates the writer has no destination to serialize Ogg pages into.

Source

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

	maxOpusPacketSamples               = opusGranuleSampleRate * 120 / 1000
	defaultChannelCount                = 2
	channelMappingFamily0              = 0
	channelMappingFamily1              = 1
	channelMappingFamily2              = 2
	channelMappingFamily255            = 255
	idPageSignature                    = "OpusHead"
	commentPageSignature               = "OpusTags"
	defaultVendor                      = "pion"
	pageHeaderSignature                = "OggS"
	pageHeaderSize                     = 27
	maxOggPageSegments                 = 255
	noGranulePosition                  = ^uint64(0)
	maxUint32Length                    = uint64(1<<32 - 1)
)

var (
	errFileNotOpened        = errors.New("file not opened")
	errOutputNotOpened      = errors.New("output not opened")
	errInvalidNilPacket     = errors.New("invalid nil packet")
	errDuplicateTrackSSRC   = errors.New("duplicate Ogg track SSRC")
	errDuplicateTrackSerial = errors.New("duplicate Ogg track serial")
	errTracksStarted        = errors.New("cannot add Ogg tracks after writing has started")
	errPacketSSRCMismatch   = errors.New("RTP packet SSRC does not match Ogg track SSRC")
	errInvalidOpusPacket    = errors.New("invalid Opus packet")
	errInvalidChannelCount  = errors.New("invalid channel count")
	errInvalidChannelMap    = errors.New("invalid channel mapping")
	errInvalidOpusTags      = errors.New("invalid OpusTags")
)

type pageRewriter interface {
	io.Seeker
	io.WriterAt
}

type writerConfig struct {
	sampleRate     uint32

View on GitHub (pinned to 8c25dc09fa)

Solutions

  1. Create/open the destination and check its error before NewWriter
  2. Never construct Writer directly without a stream; use NewWriter
  3. Verify the file is not closed/nil before each WriteRTP/Close sequence

Example fix

// before
f, _ := os.Create("out.ogg")
w, err := oggwriter.NewWriter(f) // errOutputNotOpened if f nil
// after
f, err := os.Create("out.ogg")
if err != nil {
    return err
}
w, err := oggwriter.NewWriter(f)
Defensive patterns

Strategy: validation

Validate before calling

if out == nil {
    return errors.New("ogg writer requires a non-nil io.Writer")
}
w, err := oggwriter.NewWriter(out)

Type guard

func hasOutputStream(w *oggwriter.Writer) bool {
    return w != nil
}

Try / catch

w, err := oggwriter.NewWriter(out)
if errors.Is(err, oggwriter.ErrOutputNotOpened) {
    return fmt.Errorf("ogg output missing: %w", err)
}

Prevention

When it happens

Trigger: NewWriter(nil) (oggwriter.go:391); internal write path encountering w.stream == nil (oggwriter.go:432); asserted by TestOggWriter_NewWriterRequiresOutput.

Common situations: Ignoring the error from os.Create so a nil file reaches NewWriter, constructing a Writer via a struct literal without setting stream, closing the file and continuing to write.

Related errors


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