tinyhumansai/openhuman · error
[ptt-audio] recorder.stop() threw
Error message
[ptt-audio] recorder.stop() threw
What it means
Recoverable guard in finalizePttAudio(): calling .stop() on a MediaRecorder whose state changed between the check and the call (or that the browser invalidated) throws synchronously. The catch warns and the flow continues waiting for the already-registered 'stop' event promise, so finalization still settles — the message records a hiccup, not a lost recording.
Source
Thrown at app/src/features/voice/pttAudio.ts:90
export async function finalizePttAudio(): Promise<FinalizedAudio> {
if (!active) {
throw new Error('[ptt-audio] finalize called with no active recorder');
}
const session = active;
active = null;
const done = new Promise<void>(resolve => {
if (session.recorder.state === 'inactive') {
resolve();
return;
}
session.recorder.addEventListener('stop', () => resolve(), { once: true });
});
try {
if (session.recorder.state !== 'inactive') session.recorder.stop();
} catch (err) {
console.warn('[ptt-audio] recorder.stop() threw', err);
}
await done;
stopTracks(session.stream);
const blob = new Blob(session.chunks, { type: session.recorder.mimeType || 'audio/webm' });
const buffer = await blob.arrayBuffer();
const durationMs = Math.round(window.performance.now() - session.startedAt);
console.debug('[ptt-audio] finalized', { durationMs, bytes: buffer.byteLength });
return { buffer, durationMs };
}
export async function cancelPttAudio(): Promise<void> {
if (!active) return;
const session = active;
active = null;
try {
if (session.recorder.state !== 'inactive') session.recorder.stop();
} catch {View on GitHub (pinned to 7491200858)
When it happens
Trigger: Thrown at app/src/features/voice/pttAudio.ts:90 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of tinyhumansai/openhuman@7491200858 (2026-08-17).
Data as JSON: /api/errors/dc88b326a075bdba.
Report an issue: GitHub.