Hmbown/CodeWhale · error · anyhow::Error
private lane environment exceeds {} bytes
Error message
private lane environment exceeds {} bytes What it means
Thrown by write_lane_environment when the JSON serialization of the environment pairs exceeds MAX_ENVIRONMENT_BYTES, a fixed 1 MiB (1024*1024 bytes) cap. The size is measured on the serialized Vec of (String, String) pairs, so both key and value text counts. The check runs before any file is written, so no partial state lands on disk.
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 0c42157ee5)
Solutions
- Trim the environment to only the variables the lane actually needs
- Move large blobs (certs, key material) to a file inside the worktree/workspace and pass its path via a small env var
- If forwarding ambient env, filter to an allowlist of variable names instead of passing everything
Example fix
// before
environment: vec![("CA_BUNDLE".into(), std::fs::read_to_string("ca.pem")?)], // ~2 MB inline
// after
environment: vec![("CA_BUNDLE_PATH".into(), "/workspace/ca.pem".into())], Defensive patterns
Strategy: validation
Validate before calling
const MAX_ENVIRONMENT_BYTES: usize = 1024 * 1024;
let encoded = serde_json::to_vec(&environment)?;
anyhow::ensure!(
encoded.len() as u64 <= MAX_ENVIRONMENT_BYTES as u64,
"lane environment serializes to {} bytes; trim it or pass file paths instead of blobs",
encoded.len()
); Prevention
- Pass paths to large artifacts (certs, bundles) instead of inlining their contents in env vars
- Measure the serialized size of generated environments before submitting the lane spec
- Use an allowlist when forwarding ambient environment to lanes
When it happens
Trigger: Passing large values in LaneStartSpec.environment: base64 certificates/keys, embedded JIT bundles, dumped tokens, or wholesale forwarding of a huge parent environment. Serializing tips the total past 1 MiB and the write bails.
Common situations: Trying to smuggle a cert or credentials blob through env vars because it was convenient; CI wrappers forwarding entire build environments; generated environments with multi-hundred-KB values.
Related errors
- invalid lane environment key {key:?}
- project workspace path cannot be empty
- terminal lane transition requires a terminal status
- unknown runtime backend `{other}` (use tmux|inline|vm|ci)
- serialized lane exit receipt exceeds size bound
AI-assisted analysis of Hmbown/CodeWhale@0c42157ee5 (2026-08-20).
Data as JSON: /api/errors/6ae8a2e636a09368.
Report an issue: GitHub.