{"record":{"id":"62e2c3180d04542a","repo":"nikivdev/code","slug":"ai-task-has-no-moon-workspace-root-cannot-bu","errorCode":null,"errorMessage":"AI task '{}' has no moon workspace root; cannot build cached binary","messagePattern":"AI task '(.+?)' has no moon workspace root; cannot build cached binary","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/ai_tasks.rs","lineNumber":300,"sourceCode":"    let mut cmd = moon_run_command(task, project_root, args);\n    let output = cmd.output().with_context(|| {\n        format!(\n            \"failed to run AI task {} via moon ({})\",\n            task.id,\n            task.path.display()\n        )\n    })?;\n    Ok(output)\n}\n\npub fn build_task_cached(\n    task: &DiscoveredAiTask,\n    project_root: &Path,\n    force_rebuild: bool,\n) -> Result<CachedTaskArtifact> {\n    let (workspace_dir, run_path) = resolve_moon_workspace_and_entry(task, project_root);\n    if !workspace_dir.join(\"moon.mod.json\").exists() && !workspace_dir.join(\"moon.mod\").exists() {\n        bail!(\n            \"AI task '{}' has no moon workspace root; cannot build cached binary\",\n            task.id\n        );\n    }\n\n    let cache_key = compute_cache_key(task, &workspace_dir, &run_path)?;\n    let cache_dir = ai_task_cache_root()?.join(&cache_key);\n    fs::create_dir_all(&cache_dir)\n        .with_context(|| format!(\"failed to create ai task cache dir {}\", cache_dir.display()))?;\n    let binary_path = cache_dir.join(\"task-bin\");\n    if binary_path.exists() && !force_rebuild {\n        return Ok(CachedTaskArtifact {\n            cache_key,\n            binary_path,\n            rebuilt: false,\n        });\n    }\n","sourceCodeStart":282,"sourceCodeEnd":318,"githubUrl":"https://github.com/nikivdev/code/blob/a747e741ae92c09071d0ae946ab48488adcff1ce/src/ai_tasks.rs#L282-L318","documentation":"Thrown by build_task_cached in src/ai_tasks.rs when it tries to build a cached binary for an AI task but the resolved workspace directory contains neither moon.mod.json nor moon.mod. Without a moon workspace root there is nothing to build with moon.","triggerScenarios":"run_task_cached or run_task_cached_output calls build_task_cached, and resolve_moon_workspace_and_entry returns a directory lacking moon.mod.json/moon.mod — e.g. the task lives outside a moon workspace or the marker file was moved/renamed.","commonSituations":"Running a cached AI task from a subdirectory that is not a moon module root; moon.mod.json renamed after a toolchain version change; task configured with the wrong project root.","solutions":["Run from (or point project_root at) the directory containing moon.mod.json","Initialize the workspace with a moon.mod.json/moon.mod if this task was intended to be a moon module","Skip caching and use the non-cached runner (run_task_via_moon) for non-moon tasks"],"exampleFix":"// before\nlet cached = build_task_cached(task, wrong_root, false)?;\n// after\nlet cached = build_task_cached(task, project_root.join(\"moon-workspace\"), false)?; // dir containing moon.mod.json","handlingStrategy":"validation","validationCode":"fn is_moon_workspace(dir: &Path) -> bool {\n    dir.join(\"moon.mod.json\").exists() || dir.join(\"moon.mod\").exists()\n}\nif !is_moon_workspace(project_root) { eprintln!(\"not a moon workspace\"); }","typeGuard":null,"tryCatchPattern":"if let Err(e) = build_task_cached(task, root, false) {\n    if e.to_string().contains(\"no moon workspace root\") {\n        // fall back to non-cached path\n        return run_task_via_moon(task, root, args);\n    }\n    return Err(e);\n}","preventionTips":["Confirm moon.mod.json exists at the project root before enabling cached runs","Pin the workspace layout so marker files aren't moved during refactors","Document that AI cached tasks require a moon workspace"],"tags":["moon","missing-file","workspace-config","build"],"backgroundTag":"missing-workspace-root","analyzedSha":"a747e741ae92c09071d0ae946ab48488adcff1ce","analyzedAt":"2026-09-01T22:43:55.719Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}