nikivdev/code · error
Template path is not a directory: {}
Error message
Template path is not a directory: {} What it means
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.
Source
Thrown at src/code.rs:107
pub fn new_from_template(opts: NewOpts) -> Result<()> {
let template_root = config::expand_path(DEFAULT_TEMPLATE_ROOT);
// Get template name (fuzzy select if not provided)
let template_name = match opts.template {
Some(t) => t,
None => match fuzzy_select_template()? {
Some(t) => t,
None => return Ok(()), // User cancelled
},
};
let template_dir = template_root.join(template_name.trim());
if !template_dir.exists() {
bail!("Template not found: {}", template_dir.display());
}
if !template_dir.is_dir() {
bail!(
"Template path is not a directory: {}",
template_dir.display()
);
}
// Resolve target path:
// - No path: ./<template_name>
// - Starts with ./ or ../: relative to cwd
// - Starts with ~ or /: absolute path
// - Otherwise: relative to ~/code/
let target = match opts.path {
None => std::env::current_dir()?.join(&template_name),
Some(p) => {
let trimmed = p.trim();
if trimmed.starts_with("./")
|| trimmed.starts_with("../")
|| trimmed.starts_with('/')
|| trimmed.starts_with('~')View on GitHub (pinned to a747e741ae)
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.
Example fix
// before $ ls -la ~/new/rust-cli # -rw-r--r-- rust-cli (a zip file) $ f new rust-cli proj Error: Template path is not a directory: /home/user/new/rust-cli // after $ cd ~/new && mkdir rust-cli && unzip rust-cli.zip -d rust-cli/ $ f new rust-cli proj
Defensive patterns
Strategy: validation
Validate before calling
// Shell: require the template entry to be a real directory
TPL="$HOME/new/$TEMPLATE_NAME"
[ -d "$TPL" ] && [ ! -L "$TPL" -o -d "$TPL/" ] || { echo "not a directory: $TPL"; exit 1; } Type guard
fn is_valid_template(name: &str) -> bool {
let p = config::expand_path("~/new").join(name.trim());
p.is_dir() // is_dir() is false for plain files and broken symlinks
} Try / catch
match new_from_template(opts) {
Err(e) if e.to_string().contains("not a directory") => {
eprintln!("Extract the template archive into ~/new/<name>/ and retry.");
}
other => other?,
} Prevention
- 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`
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Template not found: {}
- Usage: f migrate <target> OR f migrate <source> <target> OR
- Source folder does not exist: {}
- enable-global is only supported for Codex sessions; use `f c
- agent run requires a non-empty query
AI-assisted analysis of nikivdev/code@a747e741ae (2026-09-01).
Data as JSON: /api/errors/390f7469b8e42672.
Report an issue: GitHub.