{"record":{"id":"390f7469b8e42672","repo":"nikivdev/code","slug":"template-path-is-not-a-directory","errorCode":null,"errorMessage":"Template path is not a directory: {}","messagePattern":"Template path is not a directory: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/code.rs","lineNumber":107,"sourceCode":"pub fn new_from_template(opts: NewOpts) -> Result<()> {\n    let template_root = config::expand_path(DEFAULT_TEMPLATE_ROOT);\n\n    // Get template name (fuzzy select if not provided)\n    let template_name = match opts.template {\n        Some(t) => t,\n        None => match fuzzy_select_template()? {\n            Some(t) => t,\n            None => return Ok(()), // User cancelled\n        },\n    };\n\n    let template_dir = template_root.join(template_name.trim());\n\n    if !template_dir.exists() {\n        bail!(\"Template not found: {}\", template_dir.display());\n    }\n    if !template_dir.is_dir() {\n        bail!(\n            \"Template path is not a directory: {}\",\n            template_dir.display()\n        );\n    }\n\n    // Resolve target path:\n    // - No path: ./<template_name>\n    // - Starts with ./ or ../: relative to cwd\n    // - Starts with ~ or /: absolute path\n    // - Otherwise: relative to ~/code/\n    let target = match opts.path {\n        None => std::env::current_dir()?.join(&template_name),\n        Some(p) => {\n            let trimmed = p.trim();\n            if trimmed.starts_with(\"./\")\n                || trimmed.starts_with(\"../\")\n                || trimmed.starts_with('/')\n                || trimmed.starts_with('~')","sourceCodeStart":89,"sourceCodeEnd":125,"githubUrl":"https://github.com/nikivdev/code/blob/a747e741ae92c09071d0ae946ab48488adcff1ce/src/code.rs#L89-L125","documentation":"Thrown by new_from_template (src/code.rs:107) when the resolved template path exists under ~/new/ but is a file (or other non-directory) rather than a directory. Templates are expected to be directory trees that get copied, so a plain file at that path is invalid.","triggerScenarios":"Running `f new <name> ...` where ~/new/<name> exists as a regular file — e.g. a stray file or symlink-to-file was left in the template root, or the template was replaced by a tarball/archive without extracting.","commonSituations":"Dropping a downloaded zip into ~/new/ and trying to use it directly; a leftover notes file with the same name as a former template; a broken symlink pointing to a file.","solutions":["Inspect the path from the error (`ls -la ~/new/<name>`) and remove/replace the non-directory entry.","Extract the template archive into a real directory: `mkdir -p ~/new/<name> && tar -xzf <file> -C ~/new/<name>`.","Fix or remove a broken symlink so the target is a directory.","If it's a stray file, move it out of ~/new/ to keep the template root clean."],"exampleFix":"// before\n$ ls -la ~/new/rust-cli   # -rw-r--r-- rust-cli (a zip file)\n$ f new rust-cli proj\nError: Template path is not a directory: /home/user/new/rust-cli\n// after\n$ cd ~/new && mkdir rust-cli && unzip rust-cli.zip -d rust-cli/\n$ f new rust-cli proj","handlingStrategy":"validation","validationCode":"// Shell: require the template entry to be a real directory\nTPL=\"$HOME/new/$TEMPLATE_NAME\"\n[ -d \"$TPL\" ] && [ ! -L \"$TPL\" -o -d \"$TPL/\" ] || { echo \"not a directory: $TPL\"; exit 1; }","typeGuard":"fn is_valid_template(name: &str) -> bool {\n    let p = config::expand_path(\"~/new\").join(name.trim());\n    p.is_dir() // is_dir() is false for plain files and broken symlinks\n}","tryCatchPattern":"match new_from_template(opts) {\n    Err(e) if e.to_string().contains(\"not a directory\") => {\n        eprintln!(\"Extract the template archive into ~/new/<name>/ and retry.\");\n    }\n    other => other?,\n}","preventionTips":["Always extract template archives into a directory before registering them","Keep ~/new/ free of stray files — directories only","Check for broken symlinks with `find ~/new -xtype f`"],"tags":["invalid-path","cli","rust","argument-error"],"backgroundTag":"path-is-not-a-directory","analyzedSha":"a747e741ae92c09071d0ae946ab48488adcff1ce","analyzedAt":"2026-09-01T22:43:55.719Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}