{"record":{"id":"cebf0e529cba221a","repo":"volta-cli/volta","slug":"the-exe-extension-is-not-allowed-for-directory","errorCode":null,"errorMessage":"the `.exe` extension is not allowed for directory names","messagePattern":"the `\\.exe` extension is not allowed for directory names","errorType":"validation","errorClass":"syn::Error","httpStatus":null,"severity":"error","filePath":"crates/volta-layout-macro/src/ast.rs","lineNumber":146,"sourceCode":"    /// Lowers the directory to a flattened intermediate representation.\n    fn flatten(self, results: &mut Ir, context: Vec<LitStr>) -> Result<()> {\n        let mut visited_entries = HashMap::new();\n\n        for pair in self.entries.into_pairs() {\n            let (prefix, punc) = pair.into_tuple();\n\n            let mut entry = Entry {\n                name: prefix.name,\n                context: context.clone(),\n                filename: prefix.filename.clone(),\n            };\n\n            match punc {\n                Some(FieldContents::Dir(dir)) => {\n                    let filename = prefix.filename.value();\n\n                    if filename.ends_with(\".exe\") || filename.ends_with(\"[.exe]\") {\n                        let error = syn::Error::new(\n                            prefix.filename.span(),\n                            \"the `.exe` extension is not allowed for directory names\",\n                        );\n                        return Err(error.to_compile_error());\n                    }\n\n                    if let Some(kind) = visited_entries.get(&filename) {\n                        let message = match kind {\n                            EntryKind::Exe => {\n                                format!(\"filename `{}` is a duplicate of `{}` executable on non-Windows operating systems\", filename, filename)\n                            }\n                            _ => {\n                                format!(\"duplicate filename `{}`\", filename)\n                            }\n                        };\n                        let error = syn::Error::new(prefix.filename.span(), message);\n                        return Err(error.to_compile_error());\n                    }","sourceCodeStart":128,"sourceCodeEnd":164,"githubUrl":"https://github.com/volta-cli/volta/blob/5eedd5fb2f682baceb47a242289111fcd79435a5/crates/volta-layout-macro/src/ast.rs#L128-L164","documentation":"This is a compile-time error from the layout! proc macro. Within a layout! declaration, the `[.exe]` suffix marks an entry whose on-disk name is `name` on Windows and `name.exe` elsewhere; a directory whose name literally ends in `.exe` (or `[.exe]`) is therefore rejected, since Volta's layout models executables, not directories, with those names. The macro emits a syn compile error pointing at the offending string literal.","triggerScenarios":"Declaring a directory entry in a layout! invocation whose filename literal ends with \".exe\" or \"[.exe]\", e.g. `\"tools/.exe\": dir { ... }` or `\"bin/tools[.exe]\": dir { ... }`.","commonSituations":"Copy-pasting a Windows executable layout and mistakenly giving the directory the .exe name; confusing the `[.exe]` marker syntax (which belongs on executables) with directory entries; typos placing the marker on the wrong field.","solutions":["Remove the \".exe\" / \"[.exe]\" suffix from the directory's filename literal in the layout! block","If a nested executable was intended, declare it as a file entry with the `[.exe]` suffix instead of a braced directory","Rename the directory so its name does not end in .exe"],"exampleFix":"// before\n\"bin/tools[.exe]\": dir { ... }\n// after\n\"bin/tools\": dir { \"shim[.exe]\": file; }","handlingStrategy":"validation","validationCode":"fn valid_dir_name(name: &str) -> bool { !name.ends_with(\".exe\") && !name.ends_with(\"[.exe]\") }\n// check every directory literal in the layout! block before compiling","typeGuard":null,"tryCatchPattern":"// proc-macro compile error: fix the source; no runtime catch applies.\n// In CI, fail fast with: cargo check 2>&1 | grep 'not allowed for directory names'","preventionTips":["Reserve the .exe / [.exe] suffixes for executable file entries only","Never end directory name literals with .exe or [.exe] in layout! blocks","Review Windows-specific layout templates when adapting them for directories"],"tags":["proc-macro","compile-time","rust","volta-layout"],"backgroundTag":"invalid-argument-value","analyzedSha":"5eedd5fb2f682baceb47a242289111fcd79435a5","analyzedAt":"2026-09-08T00:01:15.963Z","contentChangedAt":"2026-09-08T00:01:15.963Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}