astrid-runtime/astrid · error · std::io::Error::InvalidData

REPL history exceeds

Error message

REPL history exceeds {MAX_HISTORY_BYTES} bytes

What it means

Thrown by read_history_bounded when the REPL history file is larger than the allowed MAX_HISTORY_BYTES cap. The function reads at most MAX_HISTORY_BYTES+1 bytes and returns InvalidData if the file did not fit, protecting memory from unbounded history files.

Solutions

  1. Delete or truncate the REPL history file to bring it under MAX_HISTORY_BYTES
  2. Back up the history, trim old entries, and re-run the command
  3. Raise MAX_HISTORY_BYTES if the cap is genuinely too small for your workflow

Example fix

// before: read unbounded
let mut file = File::open(path)?;
file.read_to_end(&mut bytes)?;
// after: truncate oversized history or raise cap
if metadata.len() > MAX_HISTORY_BYTES {
    std::fs::write(path, b"")?; // reset oversized history
}
Defensive patterns

Strategy: validation

Validate before calling

if let Ok(md) = std::fs::metadata(&history_path) {
    if md.len() > MAX_HISTORY_BYTES {
        // truncate/back up before calling read_history_bounded
        std::fs::write(&history_path, b"")?;
    }
}

Try / catch

match read_history_bounded(&path) {
    Ok(bytes) => use_history(bytes),
    Err(e) if e.kind() == io::ErrorKind::InvalidData => reset_history(&path),
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling read_history_bounded (directly or via migrate_legacy_history) when the history file on disk exceeds MAX_HISTORY_BYTES bytes.

Common situations: A history file accumulated over years of REPL use, an imported/merged history from another tool, or a corrupted file that grew without bound.

Understand the failure class

Background: "File too large" / "file size exceeds limit" errors: why libraries cap file sizes and how to fix them — this error's family across 46 libraries.

Related errors


AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09). Data as JSON: /api/errors/6aea484300b8f003. Report an issue: GitHub.

Appendix: source

Thrown at crates/astrid-cli/src/repl.rs:268

        },
        Err(error) if error.kind() == io::ErrorKind::NotFound => {
            astrid_core::platform_fs::atomic_write_private_file(new_path, &legacy)?;
        },
        Err(error) => return Err(error),
    }
    std::fs::remove_file(legacy_path)?;
    Ok(())
}

fn read_history_bounded(path: &Path) -> io::Result<Vec<u8>> {
    astrid_core::platform_fs::verify_no_redirects(path)?;
    let mut file = File::open(path)?;
    let mut bytes = Vec::new();
    file.by_ref()
        .take(MAX_HISTORY_BYTES.saturating_add(1))
        .read_to_end(&mut bytes)?;
    if bytes.len() as u64 > MAX_HISTORY_BYTES {
        return Err(io::Error::new(
            io::ErrorKind::InvalidData,
            format!("REPL history exceeds {MAX_HISTORY_BYTES} bytes"),
        ));
    }
    Ok(bytes)
}

#[cfg(test)]
mod tests {
    use super::migrate_legacy_history;

    #[test]
    fn legacy_history_moves_to_operator_log() {
        let root = tempfile::tempdir().expect("tempdir");
        let legacy = root.path().join("history");
        let current = root.path().join("log/cli/history");
        std::fs::create_dir_all(current.parent().unwrap()).unwrap();
        std::fs::write(&legacy, b"/help\nhello\n").unwrap();

View on GitHub (pinned to affd8760f4)