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
- Inspect the DataType stored on the failing buffer and add a matching arm to the match in dequeue_buffer_and_render
- Ensure every buffer queued via add_buffer sets a supported DataType (Dma or MemFd)
- 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
- Set DataType explicitly for every buffer in add_buffer
- Handle all DataType variants exhaustively with named arms instead of raw-value guards
- Keep pipewire negotiation and buffer handling in version lockstep
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)