moeru-ai/airi · error · Error
Invalid VRAM override
Error message
Invalid VRAM override: ${bytes} (expected null or non-negative finite number) What it means
Thrown by setEstimatedVRAMOverride in packages/stage-shared/src/webgpu/detect.ts when `bytes` is neither null nor a finite non-negative number. The function explicitly accepts null (to clear the override) and any number >= 0 including 0; NaN, Infinity, and negatives are rejected because they cannot represent a VRAM quantity in bytes.
Solutions
- Parse and validate before calling: const n = Number(value); if (value === null || (Number.isFinite(n) && n >= 0)) setEstimatedVRAMOverride(value === null ? null : n)
- Convert units explicitly: GB input -> bytes via Math.round(gb * 1024**3)
- Use null (not -1 or 0-by-accident) to clear the override — 0 is a legitimate value and will not clear it
- Store the preference as a number (JSON) so it round-trips without re-parsing
Example fix
// before
setEstimatedVRAMOverride(parseFloat(input)) // NaN when input === '8 GB'
// after
const parsed = /^\s*(\d+(?:\.\d+)?)\s*(gb)?\s*$/i.exec(input)
if (!parsed) throw new Error('Enter a value like "8" or "8 GB"')
setEstimatedVRAMOverride(Math.round(Number.parseFloat(parsed[1]) * 1024 ** 3)) Defensive patterns
Strategy: validation
Validate before calling
function toVRAMOverride(value: string | number | null): number | null {
if (value === null || value === '') return null
const n = typeof value === 'number' ? value : Number(value.replace(/gb/i, '').trim())
if (!Number.isFinite(n) || n < 0) return null // or throw a user-facing message
return Math.round(n * (/(?<=\d)\s*gb/i.test(String(value)) ? 1024 ** 3 : 1))
}
setEstimatedVRAMOverride(toVRAMOverride(userInput)) Type guard
const isVRAMOverride = (v: unknown): v is number | null => v === null || (typeof v === 'number' && Number.isFinite(v) && v >= 0)
Try / catch
catch (e) { if (e.message.includes('Invalid VRAM override')) { resetInputToNull(); return } throw e } Prevention
- Normalize units (GB vs bytes) before calling
- Pass null, never -1, to clear the override
- Store the preference as a number so it round-trips without parsing
When it happens
Trigger: Calling setEstimatedVRAMOverride(NaN) after parseFloat fails on input like '8 GB'; passing -1 as a 'no override' sentinel; passing Infinity from a division by zero (bytes / 0); passing a string like '8589934592' instead of a number.
Common situations: Wiring the documented 'I have 8 GB VRAM' preference UI: parsing '8 GB' with Number() yields NaN; unit conversion mistakes (GB vs GiB vs bytes) producing fractional or negative intermediate values; passing a value read from localStorage that was stored as a string.
Related errors
- [BG Removal Worker] WebGPU not available, falling back to…
- Failed to initialize speech provider
- [GPU] Memory pressure
- [Kokoro Worker] Failed with dtype=
- [KokoroAdapter] device-loss events recorded, promoting load…
AI-assisted analysis of moeru-ai/airi@677329427f (2026-08-18).
Data as JSON: /api/errors/17c99eecb0c2f92d.
Report an issue: GitHub.
Appendix: source
Thrown at packages/stage-shared/src/webgpu/detect.ts:226
* Simple boolean helper that matches the old `isWebGPUSupported()` API.
* Prefer `detectWebGPU()` when you need more detail.
*/
export async function isWebGPUSupported(): Promise<boolean> {
// Fast-path: if gpuu's lightweight check is enough
return gpuuIsSupported()
}
/**
* Override the estimated VRAM value. Pass `null` to clear the override and
* revert to the heuristic. The override applies to future detections, and if
* a result is already cached its VRAM fields are updated immediately, so
* `resetWebGPUCache()` is not required.
*
* Intended for user preference UI ("I have 8 GB VRAM") and testing.
*/
export function setEstimatedVRAMOverride(bytes: number | null): void {
if (bytes !== null && (!Number.isFinite(bytes) || bytes < 0))
throw new Error(`Invalid VRAM override: ${bytes} (expected null or non-negative finite number)`)
vramOverride = bytes
// If we already have a cached result, update it in-place so consumers
// see the new value without needing to call resetWebGPUCache(). The
// original heuristic value is preserved in `cachedHeuristicVRAM` so we
// can revert when the override is cleared.
if (cachedResult) {
const vram = resolveVRAM(cachedHeuristicVRAM)
cachedResult = {
...cachedResult,
estimatedVRAM: vram.bytes,
estimatedVRAMSource: vram.source,
}
}
}
/** Read the current VRAM override, or null if unset. */View on GitHub (pinned to 677329427f)