{"record":{"id":"230b5ed669bf0857","repo":"xai-org/grok-build","slug":"invalid-workflow-run-id","errorCode":null,"errorMessage":"invalid workflow run id","messagePattern":"invalid workflow run id","errorType":"validation","errorClass":"std::io::Error","httpStatus":null,"severity":"error","filePath":"crates/codegen/xai-grok-shell/src/session/workflow/store.rs","lineNumber":295,"sourceCode":"        validate_run_id(run_id).ok()?;\n        self.sources.lock().contains_key(run_id).then_some(())?;\n        Some(self.run_dir(run_id)?.join(\"script.rhai\"))\n    }\n\n    fn run_dir(&self, run_id: &str) -> Option<PathBuf> {\n        self.session_dir\n            .as_ref()\n            .map(|dir| dir.join(\"workflows\").join(run_id))\n    }\n}\n\npub(crate) fn validate_run_id(run_id: &str) -> io::Result<()> {\n    if run_id.is_empty()\n        || !run_id\n            .bytes()\n            .all(|b| b.is_ascii_alphanumeric() || b == b'_' || b == b'-')\n    {\n        return Err(io::Error::new(\n            io::ErrorKind::InvalidInput,\n            \"invalid workflow run id\",\n        ));\n    }\n    Ok(())\n}\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: {}\",","sourceCodeStart":277,"sourceCodeEnd":313,"githubUrl":"https://github.com/xai-org/grok-build/blob/bc7f02eddd3d84085849dc19ed216f11c23b0571/crates/codegen/xai-grok-shell/src/session/workflow/store.rs#L277-L313","documentation":"validate_run_id enforces that a workflow run id is non-empty and contains only ASCII alphanumeric characters, '_' or '-'. It returns InvalidInput with this message otherwise. This prevents run ids from escaping their directory (path traversal) or producing unusable file names.","triggerScenarios":"register() or script_copy_path() called with an empty run id or one containing '/', '..', spaces, unicode, or other punctuation, e.g. a user-supplied or externally generated run identifier.","commonSituations":"Run ids derived from URLs, timestamps with separators like ':' or '/', user input passed through unvalidated, or empty ids when a workflow failed to allocate an id.","solutions":["Sanitize the run id to [A-Za-z0-9_-]+ before calling register/script_copy_path","Reject empty ids at the workflow creation boundary","Generate ids from a vetted source (uuid simple format) instead of user input"],"exampleFix":"// before\nstore.register(&user_provided_id, ...)?; // \"2024/01/01\" -> invalid workflow run id\n// after\nlet id: String = user_provided_id.chars().filter(|c| c.is_ascii_alphanumeric() || *c=='_' || *c=='-').collect();\nlet id = if id.is_empty() { uuid::Uuid::now_v7().simple().to_string() } else { id };\nstore.register(&id, ...)?;","handlingStrategy":"validation","validationCode":"fn valid_run_id(id: &str) -> bool {\n    !id.is_empty()\n        && id.bytes().all(|b| b.is_ascii_alphanumeric() || b == b'_' || b == b'-')\n}\n// call before: if !valid_run_id(&id) { reject }","typeGuard":"fn as_run_id(s: &str) -> Option<&str> {\n    match s {\n        s if !s.is_empty() && s.bytes().all(|b| b.is_ascii_alphanumeric() || b == b'_' || b == b'-') => Some(s),\n        _ => None,\n    }\n}","tryCatchPattern":"if let Err(e) = store.validate_run_id(&id) {\n    return Err(UserInputError::new(\"run id must match [A-Za-z0-9_-]+\", e));\n}\nlet manifest = store.register(&id, ...)?;","preventionTips":["Validate run ids at the API boundary before any store call","Generate ids from uuid simple format or base64url-free schemes","Never build run ids from raw URLs, timestamps with ':'/'/', or user free-text","Add a unit test that rejects ids containing '..', '/', spaces, and unicode"],"tags":["validation","invalid-input","path-safety"],"backgroundTag":"invalid-workflow-run-id","analyzedSha":"bc7f02eddd3d84085849dc19ed216f11c23b0571","analyzedAt":"2026-08-31T04:59:42.031Z","schemaVersion":2},"datasetVersion":"2026-08-31T09:17:48.483Z"}