Zackriya-Solutions/meetily · info
Buffer should always be available
Error message
Buffer should always be available
What it means
PooledBuffer.as_mut() expects the inner Option<Vec<f32>> to be Some. It is Some from construction and is only taken by into_inner (which consumes self) and by Drop, so a None here requires using the wrapper while Drop is running (reentrant drop) or unsafe/mem::forget misuse. In correct code this invariant cannot be violated.
Source
Thrown at frontend/src-tauri/src/audio/buffer_pool.rs:91
/// RAII wrapper that automatically returns buffer to pool when dropped
pub struct PooledBuffer {
buffer: Option<Vec<f32>>,
pool: AudioBufferPool,
}
impl PooledBuffer {
/// Create a new pooled buffer
pub fn new(pool: AudioBufferPool) -> Self {
let buffer = pool.get_buffer();
Self {
buffer: Some(buffer),
pool,
}
}
/// Get mutable access to the underlying buffer
pub fn as_mut(&mut self) -> &mut Vec<f32> {
self.buffer.as_mut().expect("Buffer should always be available")
}
/// Get immutable access to the underlying buffer
pub fn as_ref(&self) -> &Vec<f32> {
self.buffer.as_ref().expect("Buffer should always be available")
}
/// Consume the wrapper and return the buffer (will not be returned to pool)
pub fn into_inner(mut self) -> Vec<f32> {
self.buffer.take().expect("Buffer should always be available")
}
}
impl Drop for PooledBuffer {
fn drop(&mut self) {
if let Some(buffer) = self.buffer.take() {
self.pool.return_buffer(buffer);
}View on GitHub (pinned to 0281737d87)
Solutions
- Treat the panic as a design smell: audit for any buffer.take() outside into_inner and Drop
- If it fires, run with RUST_BACKTRACE=1 to find the reentrant Drop or aliasing site
- Consider returning Option/&mut from accessors or making take-sites explicit so misuse becomes a compile error
Defensive patterns
Strategy: try-catch
Try / catch
let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
pooled.as_mut().extend_from_slice(chunk);
}));
if result.is_err() {
log::error!("audio worker panicked; replacing pooled buffer");
*pooled = PooledBuffer::new(pool.clone());
} Prevention
- Do not implement Drop on structs that hold PooledBuffer and touch them in drop
- Keep take() calls confined to into_inner and Drop
- Isolate audio worker loops with catch_unwind or dedicated threads so a panic cannot kill the app
When it happens
Trigger: A Drop implementation on a struct containing PooledBuffer that calls as_mut on it during teardown, refactoring that adds an early buffer.take(), or double-use after into_inner via unsafe aliasing. Normal new -> as_mut -> drop usage never triggers it.
Common situations: Almost never observed; appears after refactors that move take() outside into_inner/Drop or when wrapping PooledBuffer in types with custom Drop handlers in the audio pipeline.
Related errors
- VAD task panicked: {}
- Failed to open stdin
- Invalid regex pattern
- metadata value checked as object
- At least one model must be defined
AI-assisted analysis of Zackriya-Solutions/meetily@0281737d87 (2026-08-16).
Data as JSON: /api/errors/6ac51c5d1b49e87d.
Report an issue: GitHub.