{"record":{"id":"3da2c1f0a31f8579","repo":"astrid-runtime/astrid","slug":"variable-detail","errorCode":null,"errorMessage":"{VARIABLE} {detail}","messagePattern":"\\{VARIABLE\\} \\{detail\\}","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-core/src/dirs_run_dir.rs","lineNumber":73,"sourceCode":"    let physical_run = physical_path(&path)?;\n    let physical_root = physical_path(home.root())?;\n    if paths_are_related(&physical_run, &physical_root)\n        || directories_are_aliases(&physical_run, &physical_root)\n    {\n        return Err(io::Error::new(\n            io::ErrorKind::InvalidData,\n            format!(\n                \"{VARIABLE} overlaps the Astrid durable root: {} overlaps {}\",\n                path.display(),\n                home.root().display()\n            ),\n        ));\n    }\n    Ok(Some(physical_run))\n}\n\nfn invalid(detail: &str) -> io::Error {\n    io::Error::new(io::ErrorKind::InvalidInput, format!(\"{VARIABLE} {detail}\"))\n}\n\nfn physical_path(path: &Path) -> io::Result<PathBuf> {\n    if let Ok(physical) = std::fs::canonicalize(path) {\n        return Ok(physical);\n    }\n    let mut missing = Vec::new();\n    let mut existing_parent = path;\n    while matches!(\n        std::fs::symlink_metadata(existing_parent),\n        Err(error) if error.kind() == io::ErrorKind::NotFound\n    ) {\n        let Some(name) = existing_parent.file_name() else {\n            break;\n        };\n        missing.push(name.to_os_string());\n        existing_parent = existing_parent.parent().expect(\"parent checked above\");\n    }","sourceCodeStart":55,"sourceCodeEnd":91,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-core/src/dirs_run_dir.rs#L55-L91","documentation":"Astrid validates the ASTRID_RUN_DIR environment variable before using it and rejects malformed values with io::ErrorKind::InvalidInput. The message is `{VARIABLE} {detail}` where VARIABLE is the literal env var name; known details include: the value must not be empty, must be an absolute path, and must not contain '.' or '..' path components.","triggerScenarios":"ASTRID_RUN_DIR set to an empty string; set to a relative path like `run` or `./run`; or containing `.`/`..` components such as /var/run/../astrid. Raised by the `invalid` helper inside `resolved`, called from configured_path/validate at startup.","commonSituations":"Shell exports ASTRID_RUN_DIR='' (e.g. `export ASTRID_RUN_DIR=;` or unexpanded variable); Docker/K8s env uses a relative path; a templated config produces /var/lib/../run/astrid.","solutions":["Set ASTRID_RUN_DIR to a non-empty, absolute path with no '.' or '..' components, e.g. /run/astrid","Normalize the value in your deploy config: resolve variables before export (`export ASTRID_RUN_DIR=\"$(realpath -m \"$BASE/run\")\"`) and guard against empty expansion","Unset ASTRID_RUN_DIR entirely to use the default (home root + `run`) if you do not need a custom location"],"exampleFix":"// before\nexport ASTRID_RUN_DIR=astrid/run/../tmp   # relative + '..'\n// after\nexport ASTRID_RUN_DIR=/var/run/astrid     # absolute, clean components","handlingStrategy":"validation","validationCode":"fn run_dir_value_ok(raw: &std::ffi::OsStr) -> bool {\n    let p = std::path::PathBuf::from(raw);\n    !raw.is_empty() && p.is_absolute()\n        && !p.components().any(|c| matches!(c, std::path::Component::ParentDir | std::path::Component::CurDir))\n}","typeGuard":null,"tryCatchPattern":"match std::env::var_os(\"ASTRID_RUN_DIR\") {\n    Some(v) if !run_dir_value_ok(&v) => {\n        eprintln!(\"ASTRID_RUN_DIR must be a non-empty absolute path without '.'/'..'; using default\");\n        std::env::remove_var(\"ASTRID_RUN_DIR\");\n    },\n    _ => {},\n}","preventionTips":["Export ASTRID_RUN_DIR as an absolute, fully expanded path in shells and manifests","Normalize templated values with realpath -m before export","Guard against empty expansion (`${VAR:?}` in shell) when the variable may be unset"],"tags":["io","configuration","env-var","path-validation"],"backgroundTag":"invalid-env-var-value","analyzedSha":"affd8760f44190dbdfbec23403f4c4b642c33112","analyzedAt":"2026-09-09T21:28:12.402Z","contentChangedAt":"2026-09-09T21:28:12.402Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}