{"record":{"id":"6ae8a2e636a09368","repo":"Hmbown/CodeWhale","slug":"private-lane-environment-exceeds-bytes","errorCode":null,"errorMessage":"private lane environment exceeds {} bytes","messagePattern":"private lane environment exceeds (.+?) bytes","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/lane/src/runtime.rs","lineNumber":239,"sourceCode":"}\n\nfn valid_environment_key(key: &str) -> bool {\n    let mut chars = key.chars();\n    chars\n        .next()\n        .is_some_and(|ch| ch == '_' || ch.is_ascii_alphabetic())\n        && chars.all(|ch| ch == '_' || ch.is_ascii_alphanumeric())\n}\n\nfn write_lane_environment(path: &Path, environment: &[(String, String)]) -> Result<()> {\n    for (key, _) in environment {\n        if !valid_environment_key(key) {\n            bail!(\"invalid lane environment key {key:?}\");\n        }\n    }\n    let encoded = serde_json::to_vec(environment).context(\"serialize private lane environment\")?;\n    if encoded.len() as u64 > MAX_ENVIRONMENT_BYTES {\n        bail!(\n            \"private lane environment exceeds {} bytes\",\n            MAX_ENVIRONMENT_BYTES\n        );\n    }\n\n    let tmp_path = lane_environment_tmp_path(path);\n    remove_file_if_present(path)?;\n    remove_file_if_present(&tmp_path)?;\n    let mut options = OpenOptions::new();\n    options.create_new(true).write(true);\n    #[cfg(unix)]\n    {\n        use std::os::unix::fs::OpenOptionsExt;\n        options.mode(0o600);\n    }\n    let result = (|| {\n        let mut file = options\n            .open(&tmp_path)","sourceCodeStart":221,"sourceCodeEnd":257,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/lane/src/runtime.rs#L221-L257","documentation":"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.","triggerScenarios":"Calling start() with an environment list whose JSON encoding (as Vec<(String,String)>) exceeds MAX_ENVIRONMENT_BYTES.","commonSituations":"Dumping the entire parent process environment into a lane; embedding large blobs (tokens, certs, serialized state) in env values instead of files.","solutions":["Remove unneeded variables or reduce values so the encoded payload fits under MAX_ENVIRONMENT_BYTES.","Pass large secrets via files/paths referenced by small env vars instead of embedding them.","Chunk or split configuration into the lane's config files rather than the environment.","Check the encoded size in code before calling start() to fail with a clearer message."],"exampleFix":"// before\nlet env: Vec<_> = std::env::vars().collect(); // may exceed the byte bound\n// after\nlet env = vec![(\"LANE_TOKEN\".to_string(), token_path.display().to_string())];","handlingStrategy":"validation","validationCode":"let encoded = serde_json::to_vec(&env)?;\nif encoded.len() as u64 > MAX_ENVIRONMENT_BYTES { /* drop or externalize values before calling start() */ }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Do not dump the whole parent environment into a lane; pass an explicit allowlist.","Store large secrets in files and reference their paths via env vars.","Check encoded size in dev/test with representative data."],"tags":["environment","size-limit","payload"],"backgroundTag":"file-size-limit-exceeded","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}