{"record":{"id":"7a270488a4039f63","repo":"windmill-labs/windmill","slug":"windmill-dir-must-not-be-empty","errorCode":null,"errorMessage":"WINDMILL_DIR must not be empty","messagePattern":"WINDMILL_DIR must not be empty","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/windmill-common/src/worker.rs","lineNumber":831,"sourceCode":"    WORKER_PULL_QUERIES_FAIRNESS.store(std::sync::Arc::new(fairness_queries));\n}\n\nlazy_static::lazy_static! {\n    pub static ref WINDMILL_DIR: String = {\n        let dir = std::env::var(\"WINDMILL_DIR\")\n            .unwrap_or_else(|_| {\n                #[cfg(not(windows))]\n                { \"/tmp/windmill\".to_string() }\n                #[cfg(windows)]\n                {\n                    let temp = std::env::temp_dir();\n                    let temp_str = temp.to_string_lossy();\n                    let normalized = temp_str.trim_end_matches(&['/', '\\\\'][..]).replace('\\\\', \"/\");\n                    format!(\"{}/windmill\", normalized)\n                }\n            });\n        if dir.is_empty() {\n            panic!(\"WINDMILL_DIR must not be empty\");\n        }\n        if dir.ends_with('/') || dir.ends_with('\\\\') {\n            panic!(\"WINDMILL_DIR must not end with a trailing slash, got: {dir}\");\n        }\n        dir\n    };\n    pub static ref TMP_LOGS_DIR: String = format!(\"{}/logs\", *WINDMILL_DIR);\n    pub static ref ROOT_CACHE_DIR: String = format!(\"{}/cache/\", *WINDMILL_DIR);\n    pub static ref HUB_CACHE_DIR: String = format!(\"{}hub\", *ROOT_CACHE_DIR);\n    pub static ref HUB_RT_CACHE_DIR: String = format!(\"{}hub_rt\", *ROOT_CACHE_DIR);\n}\n\npub fn write_file(dir: &str, path: &str, content: &str) -> error::Result<File> {\n    let path = format!(\"{}/{}\", dir, path);\n    let mut file = File::create(&path).map_err(|e| {\n        tracing::error!(\"Failed to create file at {path}: {:?}\", &e);\n        e\n    })?;","sourceCodeStart":813,"sourceCodeEnd":849,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/backend/windmill-common/src/worker.rs#L813-L849","documentation":"Windmill derives all local storage paths (job dirs, cache, logs) from the WINDMILL_DIR environment variable (defaulting to a normalized temp dir when unset). At lazy-static initialization it validates the resolved value; if it resolves to an empty string the process panics immediately, since an empty root would produce invalid paths like '/logs'.","triggerScenarios":"Setting `WINDMILL_DIR=` (empty value) in the environment of a server/worker/indexer process; some orchestrators or secret injectors export the variable with an empty string.","commonSituations":"Kubernetes ConfigMap/secret with an empty value for the key; docker-compose `WINDMILL_DIR: \"\"`; shell script doing `export WINDMILL_DIR=$UNSET_VAR` where the var is empty.","solutions":["Set WINDMILL_DIR to a non-empty absolute path (e.g. /tmp/windmill) or unset the variable entirely to use the temp-dir default","Check for empty values injected by your orchestrator (k8s env, compose, systemd EnvironmentFile)","Ensure your entrypoint script does not export an empty variable from an unset prerequisite"],"exampleFix":"// before\ndocker run -e WINDMILL_DIR= ... \n// after\ndocker run -e WINDMILL_DIR=/tmp/windmill ...","handlingStrategy":"validation","validationCode":"const v = process.env.WINDMILL_DIR;\nif (v === '') throw new Error('WINDMILL_DIR is set but empty; unset it or give it a value');","typeGuard":"function hasWindmillDir(env) {\n  return typeof env.WINDMILL_DIR === 'string' && env.WINDMILL_DIR.length > 0;\n}","tryCatchPattern":null,"preventionTips":["Never set WINDMILL_DIR to an empty string in compose/k8s env blocks — omit the key instead","Validate rendered env files for empty values in CI","Audit secret/config injectors that may export empty strings"],"tags":["rust","configuration","env-var","startup"],"backgroundTag":"invalid-env-var","analyzedSha":"e474e8803ce2ff5c2df09a58dab51d45f5c922ca","analyzedAt":"2026-09-03T12:38:19.024Z","contentChangedAt":"2026-09-03T12:38:19.024Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}