Hmbown/CodeWhale · error

private lane environment exceeds

Error message

private lane environment exceeds {} bytes

What it means

write_lane_environment enforces MAX_ENVIRONMENT_BYTES on the JSON-encoded environment payload before writing it to the lane's private environment file. This bound keeps the secret file small and readable by the log proxy in one bounded read.

Solutions

  1. Remove unneeded variables or reduce values so the encoded payload fits under MAX_ENVIRONMENT_BYTES.
  2. Pass large secrets via files/paths referenced by small env vars instead of embedding them.
  3. Chunk or split configuration into the lane's config files rather than the environment.
  4. Check the encoded size in code before calling start() to fail with a clearer message.

Example fix

// before
let env: Vec<_> = std::env::vars().collect(); // may exceed the byte bound
// after
let env = vec![("LANE_TOKEN".to_string(), token_path.display().to_string())];
Defensive patterns

Strategy: validation

Validate before calling

let encoded = serde_json::to_vec(&env)?;
if encoded.len() as u64 > MAX_ENVIRONMENT_BYTES { /* drop or externalize values before calling start() */ }

Prevention

When it happens

Trigger: Calling start() with an environment list whose JSON encoding (as Vec<(String,String)>) exceeds MAX_ENVIRONMENT_BYTES.

Common situations: Dumping the entire parent process environment into a lane; embedding large blobs (tokens, certs, serialized state) in env values instead of files.

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 Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/6ae8a2e636a09368. Report an issue: GitHub.

Appendix: source

Thrown at crates/lane/src/runtime.rs:239

}

fn valid_environment_key(key: &str) -> bool {
    let mut chars = key.chars();
    chars
        .next()
        .is_some_and(|ch| ch == '_' || ch.is_ascii_alphabetic())
        && chars.all(|ch| ch == '_' || ch.is_ascii_alphanumeric())
}

fn write_lane_environment(path: &Path, environment: &[(String, String)]) -> Result<()> {
    for (key, _) in environment {
        if !valid_environment_key(key) {
            bail!("invalid lane environment key {key:?}");
        }
    }
    let encoded = serde_json::to_vec(environment).context("serialize private lane environment")?;
    if encoded.len() as u64 > MAX_ENVIRONMENT_BYTES {
        bail!(
            "private lane environment exceeds {} bytes",
            MAX_ENVIRONMENT_BYTES
        );
    }

    let tmp_path = lane_environment_tmp_path(path);
    remove_file_if_present(path)?;
    remove_file_if_present(&tmp_path)?;
    let mut options = OpenOptions::new();
    options.create_new(true).write(true);
    #[cfg(unix)]
    {
        use std::os::unix::fs::OpenOptionsExt;
        options.mode(0o600);
    }
    let result = (|| {
        let mut file = options
            .open(&tmp_path)

View on GitHub (pinned to 73e0f67d83)