{"record":{"id":"ccb883745e04578c","repo":"nikivdev/code","slug":"no-docs-directory-run-f-setup-to-create-ai-doc","errorCode":null,"errorMessage":"No docs directory. Run `f setup` to create .ai/docs/","messagePattern":"No docs directory\\. Run `f setup` to create \\.ai/docs/","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src/docs.rs","lineNumber":194,"sourceCode":"        .iter()\n        .filter(|entry| entry.doc_review_state == \"blocked\")\n        .count();\n    let committed_count = pending_queue\n        .iter()\n        .filter(|entry| entry.doc_review_state == \"committed\")\n        .count();\n    println!(\n        \"\\nDoc review queue: {} pending · {} reviewed · {} promoted · {} blocked · {} committed\",\n        pending_count, reviewed_count, promoted_count, blocked_count, committed_count\n    );\n\n    Ok(())\n}\n\n/// Sync documentation with recent commits.\nfn sync_docs(project_root: &Path, docs_dir: &Path, commits: usize, dry: bool) -> Result<()> {\n    if !docs_dir.exists() {\n        bail!(\"No docs directory. Run `f setup` to create .ai/docs/\");\n    }\n\n    // Get recent commit messages and diffs\n    let output = Command::new(\"git\")\n        .args([\"log\", \"--oneline\", &format!(\"-{}\", commits)])\n        .current_dir(project_root)\n        .output()\n        .context(\"failed to run git log\")?;\n\n    let commit_list = String::from_utf8_lossy(&output.stdout);\n\n    println!(\"Analyzing {} recent commits...\\n\", commits);\n\n    for line in commit_list.lines() {\n        println!(\"  {}\", line);\n    }\n\n    if dry {","sourceCodeStart":176,"sourceCodeEnd":212,"githubUrl":"https://github.com/nikivdev/code/blob/a747e741ae92c09071d0ae946ab48488adcff1ce/src/docs.rs#L176-L212","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nf docs sync\nerror: No docs directory. Run `f setup` to create .ai/docs/\n// after\nf setup && f docs sync","handlingStrategy":"validation","validationCode":"if !Path::new(\".ai/docs\").is_dir() {\n    anyhow::bail!(\"run `f setup` first to create .ai/docs/\");\n}\nf_docs_sync()?;","typeGuard":"fn docs_dir_ready(root: &Path) -> bool {\n    root.join(\".ai/docs\").is_dir()\n}","tryCatchPattern":"match f_docs_sync() {\n    Err(e) if e.to_string().contains(\"No docs directory\") => {\n        f_setup()?;           // auto-heal: create scaffold\n        f_docs_sync()?;\n    }\n    other => other?,\n}","preventionTips":["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"],"tags":["docs","missing-directory","setup"],"backgroundTag":"missing-directory","analyzedSha":"a747e741ae92c09071d0ae946ab48488adcff1ce","analyzedAt":"2026-09-01T22:43:55.719Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}