{"record":{"id":"819a2a1f195a6d6a","repo":"clockworklabs/SpacetimeDB","slug":"failed-to-read-dir-from-template-directory-er","errorCode":null,"errorMessage":"Failed to read_dir from template directory {}: {err:#?}","messagePattern":"Failed to read_dir from template directory (.+?): (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/cli/build.rs","lineNumber":343,"sourceCode":"        )\n    });\n\n    let template_root_absolute = get_full_path_within_manifest_dir(path, &manifest_dir);\n\n    let repo_root = get_repo_root();\n\n    let mut files = Vec::new();\n    ls_recursively(&template_root_absolute, &repo_root, &mut files);\n\n    (files, make_repo_root_relative(&template_root_absolute, &repo_root))\n}\n\n/// Get all the paths of files within `root_dir`,\n/// transform them into paths relative to `repo_root`,\n/// and insert them into `out`.\nfn ls_recursively(root_dir: &Path, repo_root: &Path, out: &mut Vec<PathBuf>) {\n    for dir_ent in std::fs::read_dir(root_dir).unwrap_or_else(|err| {\n        panic!(\n            \"Failed to read_dir from template directory {}: {err:#?}\",\n            root_dir.display()\n        )\n    }) {\n        let dir_ent = dir_ent.unwrap_or_else(|err| {\n            panic!(\n                \"Got error during read_dir from template directory {}: {err:#?}\",\n                root_dir.display(),\n            )\n        });\n        let file_path = dir_ent.path();\n        let file_type = dir_ent.file_type().unwrap_or_else(|err| {\n            panic!(\n                \"Failed to get file_type for template file {}: {err:#?}\",\n                file_path.display(),\n            )\n        });\n        if file_type.is_dir() {","sourceCodeStart":325,"sourceCodeEnd":361,"githubUrl":"https://github.com/clockworklabs/SpacetimeDB/blob/6dee26c6efc2856793e12b148a59742964f5d783/crates/cli/build.rs#L325-L361","documentation":"Build-time panic in crates/cli/build.rs: `std::fs::read_dir` on the templates directory failed while recursively listing files to embed (the Nix path `list_all_files` -> `ls_recursively`). read_dir errors mean the directory could not be opened — it does not exist at the resolved absolute path, it is not a directory, or the process lacks permission. The resolved path is `{repo_root}/templates/{template}`, so a bad template entry in templates-list.json points at nothing.","triggerScenarios":"A templates-list.json entry whose directory field names a folder that does not exist under templates/; the templates tree deleted or not copied into a Docker/CI build context; filesystem permissions denying the build user.","commonSituations":"Renaming or removing a template folder without updating templates-list.json; minimal CI checkouts that skip submodules or sparse-checkout exclude templates/; building from a source archive missing the templates directory.","solutions":["Check the exact path printed in the panic: it should exist as a directory — `ls <repo_root>/templates/<template>`.","Fix the entry in templates/templates-list.json to match the on-disk directory name.","Ensure templates/ is present in the build context (fix .dockerignore, sparse-checkout patterns, submodule init).","Verify read/execute permission for the build user on that directory."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"# Verify every template directory is readable before building:\nfor d in $(jq -r '.templates[].directory' templates/templates-list.json); do\n  [ -d \"templates/$d\" ] || echo \"missing dir: templates/$d\"\n  [ -r \"templates/$d\" ] || echo \"unreadable dir: templates/$d\"\ndone","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep templates-list.json entries in sync with on-disk directory names.","Include the full templates/ tree in Docker and CI build contexts.","Add a CI step that validates the JSON list against the filesystem."],"tags":["spacetimedb","build-script","directory-not-found","templates","filesystem"],"backgroundTag":"directory-read-failed","analyzedSha":"6dee26c6efc2856793e12b148a59742964f5d783","analyzedAt":"2026-08-20T06:08:37.179Z","contentChangedAt":"2026-08-20T06:08:37.179Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}