nikivdev/code · error · anyhow::Error
No docs directory. Run `f setup` to create .ai/docs/
Error message
No docs directory. Run `f setup` to create .ai/docs/
What it means
Raised by `sync_docs` (src/docs.rs:194) when the `.ai/docs/` directory does not exist for the project root. Doc syncing depends on the scaffold created by `f setup`, so without it there is nothing to sync commit summaries into, and the command refuses to proceed.
Source
Thrown at src/docs.rs:194
.iter()
.filter(|entry| entry.doc_review_state == "blocked")
.count();
let committed_count = pending_queue
.iter()
.filter(|entry| entry.doc_review_state == "committed")
.count();
println!(
"\nDoc review queue: {} pending · {} reviewed · {} promoted · {} blocked · {} committed",
pending_count, reviewed_count, promoted_count, blocked_count, committed_count
);
Ok(())
}
/// Sync documentation with recent commits.
fn sync_docs(project_root: &Path, docs_dir: &Path, commits: usize, dry: bool) -> Result<()> {
if !docs_dir.exists() {
bail!("No docs directory. Run `f setup` to create .ai/docs/");
}
// Get recent commit messages and diffs
let output = Command::new("git")
.args(["log", "--oneline", &format!("-{}", commits)])
.current_dir(project_root)
.output()
.context("failed to run git log")?;
let commit_list = String::from_utf8_lossy(&output.stdout);
println!("Analyzing {} recent commits...\n", commits);
for line in commit_list.lines() {
println!(" {}", line);
}
if dry {View on GitHub (pinned to a747e741ae)
Solutions
- Run `f setup` to create the `.ai/docs/` scaffold, then retry the sync
- Verify you are in the project root and that `.ai/docs/` exists (ls .ai/docs)
- Restore the directory if a clean step removed it (re-run setup or restore from a teammate's setup)
- If the directory moved, update the tool/config to the new docs path
Example fix
// before f docs sync error: No docs directory. Run `f setup` to create .ai/docs/ // after f setup && f docs sync
Defensive patterns
Strategy: validation
Validate before calling
if !Path::new(".ai/docs").is_dir() {
anyhow::bail!("run `f setup` first to create .ai/docs/");
}
f_docs_sync()?; Type guard
fn docs_dir_ready(root: &Path) -> bool {
root.join(".ai/docs").is_dir()
} Try / catch
match f_docs_sync() {
Err(e) if e.to_string().contains("No docs directory") => {
f_setup()?; // auto-heal: create scaffold
f_docs_sync()?;
}
other => other?,
} Prevention
- Always run `f setup` after fresh clones
- Exclude `.ai/docs` from clean/deep-clean scripts
- Run docs commands from the project root, not subdirectories
- Check `.ai/docs` exists in CI before doc-sync steps
When it happens
Trigger: Running `f docs sync` (or the command dispatching to `sync_docs`) in a project where `.ai/docs/` was deleted, was never created because `f setup` was skipped, or the command was run from the wrong directory so `docs_dir` points at a non-existent location.
Common situations: Fresh clones without running setup, cleaning scripts removing `.ai/`, working in a monorepo subdirectory instead of the project root, or a renamed docs directory after a template change.
Related errors
- Docs template not found at {}
- Flow Codex wrapper is missing at {}; build or sync Flow firs
- moon build output directory missing: {}
- No templates found in ~/new/
- session is not eligible for promotion
AI-assisted analysis of nikivdev/code@a747e741ae (2026-09-01).
Data as JSON: /api/errors/ccb883745e04578c.
Report an issue: GitHub.