can1357/oh-my-pi · error · RangeError
Audio gain must be a finite non-negative number
Error message
Audio gain must be a finite non-negative number
What it means
The streaming audio player validates gain before applying it: it must be a finite, non-negative number. NaN, Infinity, negative values, or non-numbers throw a RangeError from setGain, which is called both directly and from start().
Source
Thrown at packages/coding-agent/src/tts/streaming-player.ts:65
}
}
/** Queues one mono `f32` PCM chunk without copying it in TypeScript. */
write(pcm: Float32Array): void {
if (this.#inputClosed || this.#stopped || pcm.length === 0) return;
if (!this.#native && !this.#error) this.start(this.#sampleRate);
const native = this.#native;
if (!native) return;
try {
native.write(pcm);
} catch (cause) {
this.#failNative(native, cause);
}
}
/** Applies gain at render time, including to samples already queued natively. */
setGain(gain: number): void {
if (!Number.isFinite(gain) || gain < 0) throw new RangeError("Audio gain must be a finite non-negative number");
this.#gain = gain;
const native = this.#native;
if (!native) return;
try {
native.setGain(gain);
} catch (cause) {
this.#failNative(native, cause);
}
}
/** Closes input and resolves after every queued sample reaches the speaker. */
end(): Promise<void> {
if (this.#ending) return this.#ending;
if (this.#stopped) return Promise.resolve();
this.#inputClosed = true;
if (this.#error) {
this.#stopped = true;
return Promise.reject(this.#error);View on GitHub (pinned to 9690622007)
Solutions
- Pass a finite number >= 0, e.g. Math.max(0, Number.isFinite(v) ? v : defaultGain)
- Coerce and clamp user/config input before calling setGain or start()
- Fix the upstream computation producing NaN/Infinity (check for undefined operands or divide-by-zero)
Example fix
// before player.setGain(userVolume * multiplier); // may be NaN/negative // after const gain = Math.max(0, userVolume * multiplier); player.setGain(Number.isFinite(gain) ? gain : 1);
Defensive patterns
Strategy: validation
Validate before calling
const g = Number(gain);
if (!Number.isFinite(g) || g < 0) throw new TypeError(`invalid gain: ${gain}`);
player.setGain(g); Type guard
function isValidGain(v) {
return typeof v === 'number' && Number.isFinite(v) && v >= 0;
} Try / catch
try {
player.setGain(gain);
} catch (err) {
if (err instanceof RangeError && err.message.includes('gain')) {
player.setGain(1); // safe default
} else throw err;
} Prevention
- Clamp all user/config gain values with Math.max(0, value) before applying
- Sanitize UI slider inputs (empty fields produce NaN)
- Guard multiplicative gain computations against undefined operands and Infinity
When it happens
Trigger: Calling player.setGain(NaN), setGain(-0.5), setGain(Infinity), or setGain(undefined as any); start() propagates the same error when it applies an initial invalid gain.
Common situations: A UI slider produces NaN from an empty input or division by zero; a config value is negative ('quiet down' attempts); a computation like volume * multiplier overflows to Infinity or yields NaN from undefined operands.
Related errors
- Invalid package name: ${name}
- Invalid package name: ${name}
- Invalid log regex: ${error instanceof Error ? error.message
- Daemon name must be 1-48 letters, numbers, dots, underscores
- RPC message page limit must be between 1 and ${MAX_RPC_MESSA
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/cf2cf72e44ced42c.
Report an issue: GitHub.