block/buzz · error · Error
Cannot encode an empty voice note
Error message
Cannot encode an empty voice note
What it means
encodeVoiceNoteWav validates its inputs before building a WAV: samples must be non-empty and both input and output sample rates must be finite positive numbers. Any violation — including non-finite or non-positive rates — is reported uniformly as "Cannot encode an empty voice note" so the encoder never produces a degenerate file.
Source
Thrown at desktop/src/features/messages/lib/voiceNoteWav.ts:23
view.setUint8(offset + index, value.charCodeAt(index));
}
}
export function encodeVoiceNoteWav(
channels: readonly Float32Array[],
inputSampleRate: number,
outputSampleRate = DEFAULT_OUTPUT_SAMPLE_RATE,
): Uint8Array {
const inputLength = channels[0]?.length ?? 0;
if (
channels.length === 0 ||
inputLength === 0 ||
!Number.isFinite(inputSampleRate) ||
inputSampleRate <= 0 ||
!Number.isFinite(outputSampleRate) ||
outputSampleRate <= 0
) {
throw new Error("Cannot encode an empty voice note");
}
const frameCount = Math.max(
1,
Math.floor((inputLength * outputSampleRate) / inputSampleRate),
);
const bytes = new Uint8Array(44 + frameCount * 2);
const view = new DataView(bytes.buffer);
writeAscii(view, 0, "RIFF");
view.setUint32(4, bytes.length - 8, true);
writeAscii(view, 8, "WAVE");
writeAscii(view, 12, "fmt ");
view.setUint32(16, 16, true);
view.setUint16(20, 1, true);
view.setUint16(22, 1, true);
view.setUint32(24, outputSampleRate, true);
view.setUint32(28, outputSampleRate * 2, true);
view.setUint16(32, 2, true);View on GitHub (pinned to dad5a33865)
Solutions
- Check samples.length (and the recording duration) before calling encodeVoiceNoteWav and skip encode for empty captures.
- Verify the AudioContext sampleRate is a finite positive number before recording starts; recreate the context if it reports NaN/0.
- Confirm microphone permissions are granted so capture actually produces samples.
- Fix the resampler configuration so outputSampleRate is a valid positive constant (e.g. 16000).
Example fix
// before
const wav = encodeVoiceNoteWav(samples, ctx.sampleRate, 16000);
// after
if (samples.length === 0 || !Number.isFinite(ctx.sampleRate) || ctx.sampleRate <= 0) {
toast.error("Recording was empty — try again.");
return;
}
const wav = encodeVoiceNoteWav(samples, ctx.sampleRate, 16000); Defensive patterns
Strategy: validation
Validate before calling
const ok = samples.length > 0 && Number.isFinite(inputSampleRate) && inputSampleRate > 0 && Number.isFinite(outputSampleRate) && outputSampleRate > 0; if (!ok) skipEncodeAndNotifyUser();
Type guard
function isEncodableAudio(samples: Float32Array, inRate: number, outRate: number): boolean {
return samples.length > 0
&& Number.isFinite(inRate) && inRate > 0
&& Number.isFinite(outRate) && outRate > 0;
} Try / catch
try {
const wav = encodeVoiceNoteWav(samples, inRate, outRate);
} catch (e) {
if (e instanceof Error && e.message === "Cannot encode an empty voice note") {
toast.error("Recording was empty — hold to record again.");
return;
}
throw e;
} Prevention
- Check captured buffer length and duration before encode; discard empty takes.
- Validate AudioContext.sampleRate is finite and positive when creating the recorder.
- Assert microphone permissions before starting capture.
- Pin output sample rate to a positive constant and unit-test encode with zero-length input.
When it happens
Trigger: Recording produced zero samples (inputLength === 0), or a Float32Array of length 0 was passed, or sample rates are NaN/Infinity/<= 0 (e.g. an AudioContext with a closed/uninitialized sampleRate).
Common situations: User taps record and immediately stops (empty capture); microphone permission denied leading to an empty buffer; getFloatTimeDomainData on a torn-down AudioContext returning NaN sampleRate; resampler config bug passing 0 as output rate.
Related errors
- plugin.json unknown key "{key}"
- plugin.json defaults: unknown key "{key}"
- plugin.json defaults.triggers: unknown key "{key}"
- skill {label}: name "{name_str}" differs from directory name
- Choose a project.
AI-assisted analysis of block/buzz@dad5a33865 (2026-09-05).
Data as JSON: /api/errors/fe6ad315df54a1ec.
Report an issue: GitHub.