Skip to content

ghost_memory_save fails with UNIQUE constraint on projects.path when project has non-filesystem path #153

@wcatz

Description

@wcatz

Bug Report

Description

ghost_memory_save fails with a UNIQUE constraint error when saving memories for a project whose path field equals its id (i.e. a non-filesystem path).

Error Message

ensure project: constraint failed: UNIQUE constraint failed: projects.path (2067)

Steps to Reproduce

  1. Have a project with a non-filesystem path where id == path (e.g. a7293a04b38a)
  2. Call ghost_memory_save with either the project name (e.g. project_id="dingo") or the internal id (e.g. project_id="a7293a04b38a")
  3. Observe the error: ensure project: constraint failed: UNIQUE constraint failed: projects.path (2067)

Expected Behavior

ghost_memory_save should succeed regardless of whether the project's path field is a filesystem path or a non-filesystem identifier.

Actual Behavior

The save operation fails. ghost_list_projects shows the affected project has path: a7293a04b38a (same value as id) rather than a real filesystem path. The error suggests that the "ensure project" logic (likely an upsert or insert-if-not-exists) is performing a duplicate insert — possibly a race condition or a code path that doesn't correctly handle the case where path == id.

Additional Context

  • The error code 2067 is SQLite's SQLITE_CONSTRAINT_UNIQUE.
  • The bug affects both lookup-by-name and lookup-by-internal-id.
  • Projects with a proper filesystem path (e.g. /home/user/git/myrepo) do not appear to trigger this issue.
  • Likely cause: the ensure project function may be doing a SELECT followed by an INSERT without proper conflict handling, or the upsert clause targets the wrong unique column, causing a second insert attempt when path already exists.

Suggested Fix

Review the ensure project database logic to use an INSERT OR IGNORE / ON CONFLICT DO NOTHING (or equivalent upsert) that correctly deduplicates on projects.path, and verify it handles the id == path case without attempting a second insert.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions