tirth8205/code-review-graph · error · ValueError

Either memory_dir or repo_root required

Error message

Either memory_dir or repo_root required

What it means

save_result() requires a place to write: either an explicit memory_dir or a repo_root from which it derives <repo>/.code-review-graph/memory. Passing None for both leaves no destination, so it raises ValueError before any file IO.

Source

Thrown at code_review_graph/memory.py:38

    repo_root: Path | None = None,
) -> Path:
    """Save a Q&A result as markdown for re-ingestion.

    Args:
        question: The question that was asked.
        answer: The answer/result.
        nodes: Related node qualified names.
        result_type: Type of result (query, review, debug).
        memory_dir: Directory to save to. Defaults to
            <repo>/.code-review-graph/memory/
        repo_root: Repository root for default memory_dir.

    Returns:
        Path to the saved file.
    """
    if memory_dir is None:
        if repo_root is None:
            raise ValueError(
                "Either memory_dir or repo_root required"
            )
        memory_dir = (
            repo_root / ".code-review-graph" / "memory"
        )

    memory_dir.mkdir(parents=True, exist_ok=True)

    # Generate filename from question
    slug = re.sub(r"[^\w\s-]", "", question.lower())
    slug = re.sub(r"[\s_]+", "-", slug).strip("-")[:60]
    timestamp = int(time.time())
    filename = f"{slug}-{timestamp}.md"

    # Build markdown with YAML frontmatter
    lines = [
        "---",
        f"type: {result_type}",

View on GitHub (pinned to b58668751a)

Solutions

  1. Pass repo_root (usually Path.cwd() or the detected repo) and let it default to .code-review-graph/memory.
  2. Or pass an explicit memory_dir path; it will be created if missing.
  3. Audit call sites to ensure repo_root is resolved before save_result is invoked.

Example fix

# before
save_result(result, memory_dir=None, repo_root=None)
# after
save_result(result, repo_root=Path.cwd())
# or
save_result(result, memory_dir=Path("/var/lib/crg/memory"))
Defensive patterns

Strategy: validation

Validate before calling

from pathlib import Path
if memory_dir is None:
    memory_dir = repo_root / ".code-review-graph" / "memory" if repo_root else Path.cwd() / ".code-review-graph" / "memory"

Try / catch

try:
    save_result(result, memory_dir=memory_dir, repo_root=repo_root)
except ValueError:
    save_result(result, repo_root=Path.cwd())  # fallback

Prevention

When it happens

Trigger: Calling memory.save_result(...) with both memory_dir=None and repo_root=None — e.g. when a CLI flag for --memory-dir is omitted and repo_root was never resolved.

Common situations: Optional CLI args defaulting to None; refactors that stopped threading repo_root through call sites; calling save_result in tests or scripts outside a repository context.

Related errors


AI-assisted analysis of tirth8205/code-review-graph@b58668751a (2026-08-28). Data as JSON: /api/errors/64546e1bced1d087. Report an issue: GitHub.