Troubleshoot dashboard

Before you start

The attune-rag dashboard command runs a three-stage pipeline:

  1. Refreshbuild_snapshot() benchmarks the corpus and emits a snapshot dict. If queries.yaml is missing, it returns a partial snapshot that includes an error key rather than raising.
  2. Renderrender() writes an HTML file to the specified output path with the snapshot embedded as JSON, replacing the __ATTUNE_SNAPSHOT__ and __ATTUNE_TITLE__ sentinels in the template.
  3. Showdisplay() pretty-prints the snapshot to the terminal using Rich.

Each stage has its own source file. Knowing which stage failed narrows the search considerably before you look at any code.

Symptom table

If you observe Check
KeyError or missing fields in the snapshot Whether queries.yaml exists and is on the path passed to build_snapshot(). A missing file produces a partial snapshot with an error key, not an exception.
HTML output contains literal __ATTUNE_SNAPSHOT__ or __ATTUNE_TITLE__ The snapshot was not injected — confirm render() received a non-empty snapshot dict and that the template file is the one distributed with the package.
Terminal output is blank or garbled display() was called with an empty snapshot (check the refresh stage first) or the Rich Console instance is misconfigured.
main() returns a non-zero exit code Run the CLI with --help to confirm argument parsing, then reproduce with an explicit corpus_package value.
Intermittent missing data across runs Stale corpus registration or a queries.yaml that is updated between runs — check which file path build_snapshot() resolves at runtime.

Step-by-step diagnosis

Work through these steps in order — each one is cheaper than the next.

  1. Identify the failing stage. Run only the stage that shows the symptom:

    # Refresh only — prints the raw snapshot dict
    python -c "from attune_rag.dashboard.refresh import build_snapshot; import json; print(json.dumps(build_snapshot(), indent=2))"
    
    # Render only — write HTML to /tmp and inspect it
    python -c "
    from attune_rag.dashboard.refresh import build_snapshot
    from attune_rag.dashboard.render import render
    from pathlib import Path
    render(Path('/tmp/dash_debug.html'), build_snapshot())
    "
    
    # Show only — pretty-print the snapshot
    python -c "
    from attune_rag.dashboard.refresh import build_snapshot
    from attune_rag.dashboard.show import display
    display(build_snapshot())
    "
    
  2. Check the snapshot for an error key. build_snapshot() returns a partial dict when queries.yaml is missing. Inspect the output from step 1 for a top-level "error" key before assuming a code defect:

    python -c "
    from attune_rag.dashboard.refresh import build_snapshot
    s = build_snapshot()
    print(s.get('error', 'no error key — snapshot looks complete'))
    "
    

    If an error is present, locate queries.yaml and pass its path explicitly:

    build_snapshot(queries_path=Path('/your/path/to/queries.yaml'))
    
  3. Confirm the corpus package is registered. Both main() functions default to corpus_package='attune_help'. If you are using a different package, pass it explicitly and confirm the package is importable:

    python -c "import attune_help"
    

    A ModuleNotFoundError here means the corpus package is not installed in the active environment.

  4. Run the dashboard tests. Check which paths are already covered before modifying code:

    pytest -k "dashboard" -v
    

    A failing test that exercises your symptom gives you a reproducible baseline and fixtures you can reuse.

  5. Enable debug logging. If the above steps do not surface the problem, enable DEBUG-level logging and re-run the failing stage:

    PYTHONPATH=src python -c "
    import logging; logging.basicConfig(level=logging.DEBUG)
    from attune_rag.dashboard.refresh import build_snapshot
    build_snapshot()
    "
    

Common fixes

Source files

Tags: dashboard, living-docs, html, terminal, snapshot, freshness