{"record":{"id":"28f1dfadc997dc75","repo":"clockworklabs/SpacetimeDB","slug":"could-not-read-skills-directory-at-ensure-skil","errorCode":null,"errorMessage":"Could not read skills directory at {}. Ensure skills/ exists at the repo root.","messagePattern":"Could not read skills directory at (.+?)\\. Ensure skills/ exists at the repo root\\.","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/cli/build.rs","lineNumber":523,"sourceCode":"        _ => {\n            if let Some(parent) = path.parent() {\n                fs::create_dir_all(parent)?;\n            }\n            let mut file = fs::File::create(path)?;\n            file.write_all(contents)\n        }\n    }\n}\n\n/// Discover skill directories under skills/. Each directory containing a SKILL.md\n/// file is considered a skill. Returns sorted skill names.\nfn discover_skill_names(skills_dir: &Path) -> Vec<String> {\n    let mut names = Vec::new();\n\n    let entries = match fs::read_dir(skills_dir) {\n        Ok(entries) => entries,\n        Err(_) => {\n            panic!(\n                \"Could not read skills directory at {}. Ensure skills/ exists at the repo root.\",\n                skills_dir.display()\n            );\n        }\n    };\n\n    for entry in entries.flatten() {\n        let path = entry.path();\n        if path.is_dir()\n            && path.join(\"SKILL.md\").exists()\n            && let Some(name) = path.file_name().and_then(|n| n.to_str())\n        {\n            names.push(name.to_string());\n        }\n    }\n\n    names.sort();\n    names","sourceCodeStart":505,"sourceCodeEnd":541,"githubUrl":"https://github.com/clockworklabs/SpacetimeDB/blob/6dee26c6efc2856793e12b148a59742964f5d783/crates/cli/build.rs#L505-L541","documentation":"Build-time panic in crates/cli/build.rs: `fs::read_dir` on the skills directory failed while discovering embedded skills (each subdirectory of skills/ containing a SKILL.md). The error is swallowed and replaced by this panic, so any read failure — directory missing, not a directory, or lacking permissions — produces the same message. The build requires a skills/ directory at the repo root to generate the skill-embedding code.","triggerScenarios":"Building the CLI from a source tree where skills/ was deleted or never copied (partial clone, trimmed Docker context, source tarball); skills/ existing as a file instead of a directory; permission denial for the build user.","commonSituations":"Docker/CI contexts excluding the new skills/ directory via .dockerignore or sparse-checkout; contributors on older checkouts pulling only crates/; packaging scripts that cherry-pick directories.","solutions":["Create or restore the directory: `git checkout HEAD -- skills` (or `mkdir skills` if genuinely empty, then add at least one skill dir with SKILL.md).","Fix the build context: remove `skills` from .dockerignore/.gitignore-style exclusions and re-copy the full source.","Verify `test -d skills && test -r skills && test -x skills` for the build user.","Re-run `cargo build -p spacetimedb-cli`."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"# Before building the CLI:\ntest -d skills && test -r skills && echo \"skills ok\" || echo \"skills/ missing or unreadable\"","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Restore skills/ via `git checkout HEAD -- skills` when switching branches or cleaning.","Include skills/ in Docker/CI copy steps (check .dockerignore).","Add a CI existence check so the directory is never silently dropped."],"tags":["spacetimedb","build-script","directory-not-found","skills","filesystem"],"backgroundTag":"missing-directory","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"}