{"record":{"id":"fc5cb063e501b2cc","repo":"xai-org/grok-build","slug":"workflow-artifact-exceeds-limit-bytes","errorCode":null,"errorMessage":"workflow artifact exceeds {limit} bytes: {}","messagePattern":"workflow artifact exceeds (.+?) bytes: (.+?)","errorType":"validation","errorClass":"std::io::Error","httpStatus":null,"severity":"error","filePath":"crates/codegen/xai-grok-shell/src/session/workflow/store.rs","lineNumber":319,"sourceCode":"}\n\npub(crate) fn script_revision_path(run_dir: &Path, revision: u32) -> PathBuf {\n    run_dir.join(\"scripts\").join(format!(\"{revision:04}.rhai\"))\n}\n\npub(crate) fn read_bounded_nofollow(path: &Path, limit: u64) -> io::Result<Vec<u8>> {\n    let metadata = std::fs::symlink_metadata(path)?;\n    if metadata.file_type().is_symlink() || !metadata.is_file() {\n        return Err(io::Error::new(\n            io::ErrorKind::InvalidData,\n            format!(\n                \"workflow artifact is not a regular file: {}\",\n                path.display()\n            ),\n        ));\n    }\n    if metadata.len() > limit {\n        return Err(io::Error::new(\n            io::ErrorKind::InvalidData,\n            format!(\n                \"workflow artifact exceeds {limit} bytes: {}\",\n                path.display()\n            ),\n        ));\n    }\n    let mut options = std::fs::OpenOptions::new();\n    options.read(true);\n    #[cfg(unix)]\n    {\n        use std::os::unix::fs::OpenOptionsExt;\n        options.custom_flags(libc::O_NOFOLLOW);\n    }\n    let file = options.open(path)?;\n    let opened = file.metadata()?;\n    if !opened.is_file() || opened.len() > limit {\n        return Err(io::Error::new(","sourceCodeStart":301,"sourceCodeEnd":337,"githubUrl":"https://github.com/xai-org/grok-build/blob/bc7f02eddd3d84085849dc19ed216f11c23b0571/crates/codegen/xai-grok-shell/src/session/workflow/store.rs#L301-L337","documentation":"read_bounded_nofollow enforces a maximum artifact size. If symlink_metadata reports the file is larger than `limit` before opening, it returns InvalidData with this message to avoid unbounded memory use when loading run state.","triggerScenarios":"A workflow artifact (runs.json or a .rhai script) exceeds the configured byte limit at load time in load_workflow_runs_sync — e.g. corrupted writer, huge injected file, or a too-small limit for legitimately large runs.","commonSituations":"Run manifest grown beyond expectations after many updates; maliciously planted oversized file in the runs dir; operator lowered the limit after old runs already exceed it.","solutions":["Raise the artifact size limit to a value that accommodates legitimate run state","Inspect and truncate/compact the oversized artifact, then re-persist it","Delete the corrupt/oversized run directory and re-register the run","Find what wrote unbounded data (missing bounds in a writer) and fix it"],"exampleFix":"// before\nlet bytes = store.read_bounded_nofollow(&path, 1024)?; // legit manifest is 4 KB\n// after\nconst MAX_RUN_MANIFEST: u64 = 64 * 1024;\nlet bytes = store.read_bounded_nofollow(&path, MAX_RUN_MANIFEST)?;","handlingStrategy":"try-catch","validationCode":"fn within_limit(p: &std::path::Path, limit: u64) -> bool {\n    std::fs::symlink_metadata(p).map(|m| m.len() <= limit).unwrap_or(false)\n}","typeGuard":null,"tryCatchPattern":"match store.read_bounded_nofollow(&path, limit) {\n    Ok(bytes) => Ok(bytes),\n    Err(e) if e.kind() == std::io::ErrorKind::InvalidData\n        && e.to_string().contains(\"exceeds\") => {\n        // compact or quarantine the oversized run, do not retry blindly\n        quarantine_run_dir(&run_dir)?;\n        Ok(Vec::new())\n    }\n    Err(e) => Err(e.into()),\n}","preventionTips":["Set the artifact limit comfortably above real manifest sizes and document it","Compact run state periodically instead of appending forever","Never write log-like unbounded data into workflow artifacts","Alert when a load rejects an artifact — it usually means a corrupt writer"],"tags":["io","invalid-data","size-limit","dos-protection"],"backgroundTag":"artifact-size-exceeded","analyzedSha":"bc7f02eddd3d84085849dc19ed216f11c23b0571","analyzedAt":"2026-08-31T04:59:42.031Z","schemaVersion":2},"datasetVersion":"2026-08-31T09:17:48.483Z"}