Skip to content

[Bug] seed_one re-seed fails on UNIQUE constraint #48

Closed

Description

@nelsonmfinda

Description

seed_data.seed_one performs a plain INSERT against the documentations table, which has a UNIQUE constraint on name. Re-seeding the same corpus (same name) raises sqlite3.IntegrityError. This makes the re-scrape workflow that the new content-hash cache enables fail in its last step, even though the cache has already done its job and the JSON has already been written to disk.

Steps to reproduce

  1. king-scrape https://hono.dev/docs --name hono-test --yes (first run completes successfully and seeds the doc into docs.db).
  2. Re-run the exact same command. Pipeline goes through discover → filter → fetch → chunk → enrich → export.
  3. Auto-seed step at the end of export.save_and_index calls seed_data.seed_one(output_path).

Expected behavior

Re-seeding the same doc should be idempotent: replace the existing rows for that name (sections, FTS entries, query cache invalidation) with the new content, or no-op if _meta.content_hash matches. End user runs the same command and ends up with an updated, indexed corpus.

Actual behavior

sqlite3.IntegrityError: UNIQUE constraint failed: documentations.name

The pipeline crashes after enrichment is fully done. JSON file under .king-context/data/<name>.json is correctly written; the database just refuses the second insert.

Environment

  • King Context version (or commit SHA): v0.4.0 (upstream/main @ 9f0e5b1)
  • Install method: pip install -e '.[all]'
  • OS: macOS (Darwin 25.3.0)
  • Python version: 3.14.4
  • Node version (if installer-related): n/a
  • Claude Code / IDE / agent (if relevant): n/a

Affected component

  • MCP server (king-context)
  • CLI (kctx)
  • Scraper (king-scrape)
  • Researcher (king-research)
  • Installer (@king-context/cli)
  • Skills (.claude/skills/)
  • Documentation
  • Other (please describe)

Additional context

Workaround today is to wipe and reseed manually: python -m king_context.seed_data (full reseed) or delete the row in docs.db first.

Suggested fix: change seed_one to upsert. Either INSERT … ON CONFLICT(name) DO UPDATE followed by deleting and re-inserting the corresponding sections rows for that doc id, or wrap the whole thing in a transaction that drops the doc's prior rows first, then writes. The FTS5 external content table needs to stay consistent with sections either way.

Surfaced during end-to-end testing of #46 (content hash provenance + enrichment cache). Becomes a real ergonomic blocker once the incremental refresh in #46 (planned) lands, since re runs will be the common case rather than the edge case. Pre existing, unrelated to those PRs.

Activity

  1. added a commit that references this issue on Jun 7, 2026
    ae1f941
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions