Hmbown/CodeWhale · error · anyhow::Error

private lane environment {} exceeds {} bytes

Error message

private lane environment {} exceeds {} bytes

What it means

Raised by read_lane_environment when the private lane environment file (a JSON array of key/value pairs the parent pinned for the lane) stats larger than MAX_ENVIRONMENT_BYTES (1 MiB, runtime.rs:174). The guard prevents a corrupt, foreign, or hostile file from being read wholesale into memory. This is the first of two checks: a stat-based pre-check before fs::read.

Source

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

            reader.consume(take);
            if ended_line {
                break;
            }
        }
        if line.is_empty() && reached_eof {
            return Ok(());
        }
        append_child_output(&log_path, stream, &line)?;
        if reached_eof {
            return Ok(());
        }
    }
}

fn read_lane_environment(path: &Path) -> Result<Vec<(String, String)>> {
    let metadata = fs::metadata(path).with_context(|| format!("stat {}", path.display()))?;
    if metadata.len() > MAX_ENVIRONMENT_BYTES {
        bail!(
            "private lane environment {} exceeds {} bytes",
            path.display(),
            MAX_ENVIRONMENT_BYTES
        );
    }
    let bytes = fs::read(path).with_context(|| format!("read {}", path.display()))?;
    if bytes.len() as u64 > MAX_ENVIRONMENT_BYTES {
        bail!(
            "private lane environment {} exceeds {} bytes",
            path.display(),
            MAX_ENVIRONMENT_BYTES
        );
    }
    let environment: Vec<(String, String)> =
        serde_json::from_slice(&bytes).with_context(|| format!("parse {}", path.display()))?;
    for (key, _) in &environment {
        if !valid_environment_key(key) {
            bail!("invalid lane environment key {key:?}");

View on GitHub (pinned to 0c42157ee5)

Solutions

  1. Shrink the environment to essential keys and re-start the lane
  2. Inspect the file named in the message (ls -l / stat) and delete it if it is stale, then retry the start
  3. Move large values out of the environment and pass them via a file path or command argument
  4. If you control the writer, keep the serialized environment under 1 MiB before the lane is launched so both guards stay green

Example fix

// before
let spec = LaneStartSpec {
    command: vec!["bash".into()],
    environment: all_exports.clone(), // may exceed 1 MiB
    ..
};

// after
let environment: Vec<(String, String)> = all_exports
    .into_iter()
    .filter(|(k, _)| matches!(k.as_str(), "PATH" | "HOME" | "CODEWHALE_*"))
    .collect();
assert!(serde_json::to_vec(&environment).unwrap().len() <= 1024 * 1024);
let spec = LaneStartSpec { command: vec!["bash".into()], environment, .. };
Defensive patterns

Strategy: validation

Validate before calling

const MAX_ENVIRONMENT_BYTES: usize = 1024 * 1024;

fn environment_within_bound(environment: &[(String, String)]) -> bool {
    serde_json::to_vec(environment)
        .map(|bytes| bytes.len() <= MAX_ENVIRONMENT_BYTES)
        .unwrap_or(false)
}

// before start:
assert!(environment_within_bound(&spec.environment), "environment too large");

Prevention

When it happens

Trigger: Calling a lane start that leads to read_lane_environment(path) where fs::metadata(path).len() > 1_048_576. Concretely: LaneStartSpec environment serialized by write_lane_environment exceeded 1 MiB, or the environment path points at a stale/unrelated large file in a reused log directory.

Common situations: Passing bulky values (base64 blobs, long tokens, serialized payloads) through the lane environment; a log directory reused across lane generations so an old environment file survives; external tooling writing into the lane's private state directory.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@0c42157ee5 (2026-08-20). Data as JSON: /api/errors/524c69f3c251a0ce. Report an issue: GitHub.