nikivdev/code · error · anyhow::Error

docs/ exists but is a file: {}

Error message

docs/ exists but is a file: {}

What it means

Raised by `create_docs_scaffold_at` (src/docs.rs:355) when the target docs directory path exists but is a regular file instead of a directory. The scaffold creation cannot merge templates into or write under a file, so it aborts naming the offending path.

Source

Thrown at src/docs.rs:355

        Some(path) => {
            let raw = path.to_string_lossy();
            let expanded = config::expand_path(&raw);
            if expanded.is_absolute() {
                expanded
            } else {
                cwd.join(expanded)
            }
        }
        None => project_root.to_path_buf(),
    };
    create_docs_scaffold_at(&target_root, opts.force)
}

pub fn create_docs_scaffold_at(project_root: &Path, force: bool) -> Result<()> {
    let docs_dir = project_root.join(PROJECT_DOCS_DIR);
    if docs_dir.exists() {
        if docs_dir.is_file() {
            bail!("docs/ exists but is a file: {}", docs_dir.display());
        }
        if !force {
            let template_root = config::expand_path(DEFAULT_DOCS_TEMPLATE_ROOT);
            let template_docs = template_root.join(HUB_CONTENT_ROOT);
            if !template_docs.exists() {
                bail!("Docs template not found at {}", template_docs.display());
            }
            merge_docs_scaffold(&docs_dir, &template_docs)?;
            ensure_index_file(&docs_dir, "Docs")?;
            println!(
                "Docs already exists; merged template into {}",
                docs_dir.display()
            );
            return Ok(());
        }
        fs::remove_dir_all(&docs_dir)
            .with_context(|| format!("failed to remove {}", docs_dir.display()))?;
    }

View on GitHub (pinned to a747e741ae)

Solutions

  1. Inspect the path: `ls -la` on the printed location and confirm it is a file
  2. Move or remove the file (`mv docs docs.bak` or `rm docs`) once its contents are safe, then rerun setup
  3. If it contains wanted content, rename it to a markdown file and rerun scaffold creation
  4. Fix any symlink pointing docs at a regular file

Example fix

// before
$ ls -la docs
-rw-r--r-- docs
error: docs/ exists but is a file: /path/docs
// after
mv docs docs-notes.txt && f setup
Defensive patterns

Strategy: validation

Validate before calling

let docs = Path::new("docs");
if docs.exists() && !docs.is_dir() {
    anyhow::bail!("docs exists but is a file; move or remove it before setup");
}
f_setup()?;

Type guard

fn is_dir_or_absent(p: &Path) -> bool {
    !p.exists() || p.is_dir()
}

Try / catch

match f_setup() {
    Err(e) if e.to_string().contains("exists but is a file") => {
        eprintln!("{e:#}; rename the file and rerun setup");
    }
    other => other?,
}

Prevention

When it happens

Trigger: Calling `f setup`/docs scaffold creation where `PROJECT_DOCS_DIR` (docs/) resolves to a file: someone created a file named `docs` (no extension) at the project root, a bad archive/checkout materialized docs as a file, or a symlink pointing to a file.

Common situations: Accidental `touch docs`, a tarball extracting a `docs` file, editor tooling creating a `docs` scratch file, or leftover artifacts from a broken migration.

Related errors


AI-assisted analysis of nikivdev/code@a747e741ae (2026-09-01). Data as JSON: /api/errors/b9b76fe7d863e763. Report an issue: GitHub.