niri-wm/niri · error

unknown data type in dequeue_buffer_and_clear

Error message

unknown data type in dequeue_buffer_and_clear

What it means

dequeue_buffer_and_clear mirrors dequeue_buffer_and_render: it dispatches on the buffer's DataType to clear either a DMA-BUF or a MemFd SHM buffer. An unrecognized raw DataType falls into the catch-all and errors, meaning the buffer cannot be cleared and would be returned to the stream in an inconsistent state.

Solutions

  1. Add a handler arm for the unknown DataType or normalize buffer registration to only Dma/MemFd
  2. Log the offending raw DataType value at registration time to catch it in add_buffer
  3. Verify pipewire version compatibility with the supported DataType set

Example fix

// before
_ => Err(anyhow::anyhow!("unknown data type in dequeue_buffer_and_clear")),
// after
_ => {
    warn!("unknown data type {x}; treating as already clear");
    Ok((SyncPoint::signaled(), SharingBuf::Shm(shmbuf_default)))
}
Defensive patterns

Strategy: type-guard

Validate before calling

if supported_data_type(buf.data_type).is_none() {
    // destroy/requeue the buffer; it can never be cleared or rendered
}

Type guard

fn clearable(raw: u32) -> bool {
    raw == DataType::Dma.as_raw() || raw == DataType::MemFd.as_raw()
}

Try / catch

match dequeue_buffer_and_clear(...) {
    Err(e) if e.to_string().contains("unknown data type") => {
        // treat buffer as unusable: drop and let the stream reallocate
    }
    other => other?,
}

Prevention

When it happens

Trigger: A queued stream buffer carrying a DataType raw value outside the handled Dma/MemFd set when the buffer is dequeued for clearing before reuse.

Common situations: Pipewire negotiating a buffer type this build does not handle; internal state corruption where a buffer was registered without a proper DataType; partially supported datatype added in a newer pipewire version.

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/96e8a1e7b34b349c. Report an issue: GitHub.

Appendix: source

Thrown at src/screencasting/pw_utils.rs:1367

        unsafe {
            let spa_buffer = (*buffer).buffer;

            if self.cursor_mode == CursorMode::Metadata {
                add_invisible_cursor(spa_buffer);
            }

            let fd = (*(*spa_buffer).datas).fd;

            let res = match (*(*(*buffer).buffer).datas).type_ {
                x if x == DataType::DmaBuf.as_raw() => {
                    let dmabuf = self.inner.borrow().dmabufs[&fd].clone();
                    clear_dmabuf(renderer, dmabuf).map(|x| (x, SharingBuf::Dma))
                }
                x if x == DataType::MemFd.as_raw() => {
                    let shmbuf = self.inner.borrow().shmbufs[&fd].clone();
                    clear_shmbuf(&shmbuf).map(|()| (SyncPoint::signaled(), SharingBuf::Shm(shmbuf)))
                }
                _ => Err(anyhow::anyhow!(
                    "unknown data type in dequeue_buffer_and_clear"
                )),
            };

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

View on GitHub (pinned to 62c230a662)