copy/v86 · error · StateLoadError
Invalid info block length:
Error message
Invalid info block length:
What it means
restore_state reads the info-block length from the header and sanity-checks it: it must be non-negative and the info block must fit inside the state buffer (info_block_len + 12 < state.length). Out-of-range values mean the header or dump is corrupted, so StateLoadError('Invalid info block length: N') is thrown before the info block is parsed.
Source
Thrown at src/state.js:314
buffers.push(cpu.wasm_memory.buffer.slice(offset, offset + buffer_info.length));
cpu.zstd_read_free(ptr, front_padding + buffer_info.length);
}
position += front_padding + buffer_info.length;
}
state_object = restore_buffers(state_object, buffers);
cpu.set_state(state_object);
cpu.zstd_free_ctx(ctx);
}
else
{
const info_block_len = read_state_header(state, true);
if(info_block_len < 0 || info_block_len + 12 >= state.length)
{
throw new StateLoadError("Invalid info block length: " + info_block_len);
}
const info_block_buffer = state.subarray(STATE_INFO_BLOCK_START, STATE_INFO_BLOCK_START + info_block_len);
const info_block_obj = read_info_block(info_block_buffer);
let state_object = info_block_obj["state"];
const buffer_infos = info_block_obj["buffer_infos"];
let buffer_block_start = STATE_INFO_BLOCK_START + info_block_len;
buffer_block_start = buffer_block_start + 3 & ~3;
const buffers = buffer_infos.map(buffer_info => {
const offset = buffer_block_start + buffer_info.offset;
return state.buffer.slice(offset, offset + buffer_info.length);
});
state_object = restore_buffers(state_object, buffers);
cpu.set_state(state_object);
}
}View on GitHub (pinned to 180830d539)
Solutions
- Discard and re-capture the state file — a corrupt header usually can't be repaired safely
- Re-download the state and verify a checksum against the source
- Check that the buffer wasn't modified/sliced between capture and restore in your app
- Ensure the state was saved by a compatible emulator version (see version checks)
Example fix
// before
emulator.restore_state(corruptState); // throws deep inside
// after
try {
emulator.restore_state(state);
} catch (e) {
if (String(e).includes("Invalid info block length")) {
recoverFromBackupState();
}
} Defensive patterns
Strategy: validation
Validate before calling
function infoBlockFits(buf) {
if (!(buf instanceof Uint8Array) || buf.byteLength < 12) return false;
const infoLen = new Int32Array(buf.buffer, buf.byteOffset, 4)[2]; // STATE_INDEX_INFO_LEN
return infoLen >= 0 && infoLen + 12 < buf.byteLength;
}
if (!infoBlockFits(state)) throw new Error("corrupt state header"); Try / catch
try {
emulator.restore_state(state);
} catch (e) {
if (e instanceof StateLoadError && /Invalid info block length/.test(e.message)) {
restoreFromBackup(); // header is corrupt, not repairable
} else throw e;
} Prevention
- Store checksums with saved states and verify before restore
- Re-capture states showing header corruption — don't attempt repair
- Protect state blobs from post-capture mutation in your app
- Test storage/transfer paths for bit-level integrity
When it happens
Trigger: restore_state called with a state whose header STATE_INDEX_INFO_LEN is negative (int32 overflow/corruption) or so large the info block would run past the end of the buffer — corrupted header bytes, bit-flips in storage, or a hand-crafted/mis-sliced buffer.
Common situations: Bit rot or corruption in stored state files (disk, cloud sync); states manipulated by external tools; memory corruption between capture and restore in the same page (rare).
Related errors
- Invalid length:
- Invalid header:
- Length doesn't match header: real=... header=...
- Version mismatch: dump=... we=...
AI-assisted analysis of copy/v86@180830d539 (2026-08-31).
Data as JSON: /api/errors/fd978314ce968ab2.
Report an issue: GitHub.