Skip to content

Troubleshooting

Hansard separates provider sources, normalized archive files, derived viewer payloads, search indexes, and the background watcher. Diagnose the affected layer before choosing a repair.

First determine whether the data is absent or only hidden. In Conversations, select Reset filters, search a distinctive phrase, then set Source, Time, and Folder one at a time. If the conversation opens but looks incomplete, inspect its source and Not recorded fields rather than assuming the viewer dropped them.

Next open Settings → Indexing & Imports. Confirm the source-selection mode, Sources scanned, watcher status, rolling window, and whether search indexing is paused. Review incomplete runs covers lifecycle-only records hidden from ordinary lists. These checks distinguish an app filter problem from a watcher, importer, or index problem before the terminal diagnostics below change any state.

  1. Inspect the active archive and runtime.

    Terminal window
    hansard status
  2. Run installation and source diagnostics.

    Terminal window
    hansard doctor
  3. Check the watcher and search index separately.

    Terminal window
    hansard watcher status
    hansard index status
  4. Capture JSON when filing an issue or comparing two runs.

    Terminal window
    hansard status --json
    hansard doctor --json

Confirm that the source is in the configured list, then preview a direct import:

Terminal window
hansard config sources list
hansard import --source cursor --since all --dry-run --explain-skips

If the dry run finds candidates, run the import without --dry-run. Add --json to inspect structured imported, skipped, and error results.

Check these source-specific boundaries:

  • claude-cloud is opt-in and never part of --source all. Run hansard import claude-cloud --since all explicitly.
  • devin-cloud is opt-in the same way and needs a Devin API key in DEVIN_API_KEY or devin.apiKey. It reports a missing key as a setup note rather than an error, and skips cli-origin cloud rows that devin-cli already archives in full.
  • jules is opt-in the same way and needs a Jules API key in JULES_API_KEY or jules.apiKey; hansard doctor shows an informational row when none is set. Jules exposes no model ids or token usage, so its sessions are archived without model or spend attribution unless jules.modelHint declares one.
  • copilot-agent-cloud is opt-in and needs a GitHub token in GH_TOKEN, GITHUB_TOKEN, or copilot.token, or a signed-in GitHub CLI; hansard doctor shows an informational row when neither is available. Its agent-task metadata allows 60 requests per hour, so a run during a cooldown imports sessions without the prompt, model, and premium-request charge and says so. An unavailable transcript degrades to a metadata-only import rather than failing. These sessions report premium requests instead of tokens, so they carry no token usage or spend.
  • cursor-cloud is opt-in and needs a Cursor API key in CURSOR_API_KEY or cursor.apiKey; hansard doctor shows an informational row when none is set. The transcript comes from the legacy v0 conversation endpoint, and an agent that has been deleted or archived answers 409: it still imports as a metadata shell carrying each run’s final reply. Cloud agents expose no tool calls and no model id, so they stay unmodelled and never appear in the tool stats. Token usage is an early-access endpoint and is skipped with a warning when the account does not have it.
  • factory-cloud is opt-in and needs a Factory API key in FACTORY_API_KEY or factory.apiKey; hansard doctor shows an informational row when none is set. Every Droid Sessions API endpoint is enabled for selected organizations only, so an account without it gets one “not enabled for this organization” warning and no error. A session the local factory import already archived keeps its own transcript and only gains cloud metadata.
  • codex-cloud is opt-in and needs the Codex CLI installed and signed in; hansard doctor shows an informational row when the binary is not on PATH. A missing binary, a signed-out CLI, and an exhausted plan all produce a setup note rather than an error. The CLI returns the task record and its diff only, so these tasks carry no prompt, no assistant text, no tool calls, no model, and no token usage.
  • ChatGPT and Claude.ai histories require downloaded web exports.
  • Windsurf protobuf-only rows remain repair stubs until a downloaded trajectory is imported, optionally with its claim token.
  • Modern Cursor transcripts and historical Cursor SQLite data have different coverage; a complete manual import is the recovery path for older history.
  • Aider histories are repository-local, so the repository containing .aider.chat.history.md must still be reachable.

When doctor --deep reports an archived parser version older than the current importer, reimport that source with --since all. hansard rebuild does not rerun provider parsers.

Run a read-only inventory and storage plan against the intended archive path:

Terminal window
hansard init --dry-run --data-dir /path/to/archive

The source-byte total describes local provider history, not a download. Hansard also preserves raw records and writes normalized transcripts, events, Markdown, viewer payloads, and indexes. The displayed range keeps a separate recovery reserve available because a completely full archive filesystem can also block cleanup.

Choose a filesystem with more free space or use hansard init --skip-import to finish configuration without enumerating or copying provider history. A bounded source scan is explicitly a lower bound. Artifact capture is excluded from the projection, so leave additional space when it will be enabled. Existing shared raw-source snapshots can be reviewed without deleting them:

Terminal window
hansard prune raw-sources --dry-run

Apply a prune only after reviewing its preservation and rebuild implications.

Stream the watcher log while producing one new provider message:

Terminal window
hansard watcher logs --follow

Then test the same source directly:

Terminal window
hansard import --source cursor --since 30d --dry-run --explain-skips

If manual import works, recreate the background process and its filesystem watches:

Terminal window
hansard watcher restart

After changing the source list, a restart establishes event watchers for the new roots immediately. A repeated tick skipped: previous tick still running message means a previous pass is still active; inspect nearby log lines for the slow or failing source rather than assuming the process has stopped.

Check whether the index is paused, then rebuild it:

Terminal window
hansard index status
hansard index resume
hansard index rebuild

Use --markdown-fallback only for legacy archives that lack canonical events:

Terminal window
hansard history "migration plan" --markdown-fallback

Search filters combine. Remove --repo, --provider, --tool, or --command one at a time when diagnosing an unexpectedly empty result. --no-web-chats intentionally excludes imported non-repository web conversations.

Refresh view payloads without reading provider sources:

Terminal window
hansard rebuild --since all

Open the browser viewer directly if native-app activation fails:

Terminal window
hansard app --no-fallback
hansard web --no-open

app --no-fallback reports a missing or unsupported native app instead of silently opening the browser fallback. The default browser viewer binds to 127.0.0.1:7824; choose another port when it is occupied:

Terminal window
hansard web --no-open --port 7825

Binding beyond loopback requires a password. A bare --host binds to all interfaces and is not appropriate without a deliberate network boundary:

Terminal window
HANSARD_WEB_PASSWORD='<strong-password>' \
hansard web --host 0.0.0.0 --read-only
  • Run hansard doctor and install unzip when ZIP support is missing, or pass an extracted folder.
  • Move the export into a terminal-readable local directory if access is denied.
  • For split ChatGPT privacy exports, pass the parent User Online Activity folder rather than one conversation part.
  • Supply --username for a new export account when it cannot be inferred.
  • Use hansard import chatgpt --instructions or hansard import claude-web --instructions to print the current walkthrough.

Hansard may have preserved individual source files even after a provider rotated or deleted them. Preview safe restoration:

Terminal window
hansard restore-sources claude --dry-run

The command never overwrites existing files and never restores shared SQLite stores. Claude Code also has a dedicated preview:

Terminal window
hansard repair claude-code-backups --dry-run

After restoring source files, reimport the affected provider with --since all.

hansard doctor reports the relevant dependency and affected feature:

Tool Impact when missing
sqlite3 Required for Codex, Devin, and Cursor SQLite stores.
rg Recommended for fast recall and search.
unzip Required to read ZIP web exports; extracted folders remain usable.

When a package upgrade requires a clean local reimport, preview the update path:

Terminal window
hansard update --dry-run --since all

update clears local agent-session archive and derived import state before reimporting configured sources. Confirm that provider histories or restorable raw backups exist first. reset is broader and should be reserved for a fresh setup.