niri-wm/niri · error

unknown data type in dequeue_buffer_and_render

Error message

unknown data type in dequeue_buffer_and_render

What it means

dequeue_buffer_and_render dispatches on the buffer's DataType (Dma, MemFd, etc.). If the stored data type raw value matches none of the handled arms, the function returns this error, indicating an internal invariant violation: a buffer was queued with a data type the render path does not know how to render into.

Solutions

  1. Inspect the DataType stored on the failing buffer and add a matching arm to the match in dequeue_buffer_and_render
  2. Ensure every buffer queued via add_buffer sets a supported DataType (Dma or MemFd)
  3. Update the module to handle any newly negotiated pipewire buffer types

Example fix

// before
_ => Err(anyhow::anyhow!("unknown data type in dequeue_buffer_and_render")),
// after
data_type if data_type == DataType::DmaBuf.as_raw() => { /* dma path */ }
data_type if data_type == DataType::MemFd.as_raw() => { /* shm path */ }
_ => { log::warn!("unknown data type {data_type}, falling back to MemFd"); /* shm path */ }
Defensive patterns

Strategy: type-guard

Validate before calling

if !matches!(DataType::from_raw(buf.data_type), DataType::Dma | DataType::MemFd) {
    // skip or requeue the buffer instead of rendering it
}

Type guard

fn supported_data_type(raw: u32) -> Option<DataType> {
    match raw {
        x if x == DataType::Dma.as_raw() => Some(DataType::Dma),
        x if x == DataType::MemFd.as_raw() => Some(DataType::MemFd),
        _ => None,
    }
}

Try / catch

match dequeue_buffer_and_render(...) {
    Err(e) if e.to_string().contains("unknown data type") => {
        // log raw type, drop buffer, requeue with a supported type
    }
    other => other?,
}

Prevention

When it happens

Trigger: A pipewire stream buffer whose associated DataType raw flag is neither the DMA-BUF value nor the MemFd value at dequeue time — e.g. a new DataType variant added upstream or corrupted/never-initialized buffer state.

Common situations: Version skew between pipewire negotiation code and this module; buffer state initialized without a valid DataType; future datatype (e.g. new sharing mechanism) not yet handled in the match.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of niri-wm/niri@62c230a662 (2026-09-19). Data as JSON: /api/errors/021b0ff47a0556b1. Report an issue: GitHub.

Appendix: source

Thrown at src/screencasting/pw_utils.rs:1306

            let res = match (*(*spa_buffer).datas).type_ {
                x if x == DataType::DmaBuf.as_raw() => {
                    let dmabuf = inner_.dmabufs[&fd].clone();
                    render_to_dmabuf(renderer, damage_tracker, dmabuf, elements, states)
                        .map(|x| (x, SharingBuf::Dma))
                }
                x if x == DataType::MemFd.as_raw() => {
                    let shmbuf = inner_.shmbufs[&fd].clone();

                    let fourcc = if alpha {
                        Fourcc::Argb8888
                    } else {
                        Fourcc::Xrgb8888
                    };

                    render_to_shmbuf(renderer, damage_tracker, &shmbuf, fourcc, elements, states)
                        .map(|()| (SyncPoint::signaled(), SharingBuf::Shm(shmbuf)))
                }
                _ => Err(anyhow::anyhow!(
                    "unknown data type in dequeue_buffer_and_render"
                )),
            };

            drop(inner);
            match res {
                Ok((sync_point, buf)) => {
                    mark_buffer_as_good(pw_buffer, &mut self.sequence_counter, buf);
                    trace!("queueing buffer with seq={}", self.sequence_counter);
                    self.queue_after_sync(pw_buffer, sync_point);
                    true
                }
                Err(err) => {
                    warn!("error rendering to buffer: {err:?}");
                    return_unused_buffer(&self.stream, pw_buffer);
                    false
                }
            }

View on GitHub (pinned to 62c230a662)