Skip to content

External-provider asset sync writes project_id = nil UUID (FK violation) #2143

Description

@seb-kw

Summary: On re-sync, syncProjectAssets stamps every asset with project.ID, but for already-existing projects the upsert returns the struct with an unpopulated (uuid.Nil) ID. Assets are written against 00000000-…, violating fk_projects_assets.

Impact: Assets fail to persist when re-syncing existing external projects (first import is fine). 163 occurrences, clustered at sync runs.

Evidence (prod):

ERROR:  insert or update on table "assets" violates foreign key constraint "fk_projects_assets"
DETAIL: Key (project_id)=(00000000-0000-0000-0000-000000000000) is not present in table "projects".

All 163 are the zero UUID, all UPDATE "assets" (conflict-update branch).

Root cause:

  1. Provider projects arrive with no DB id — upsertProjects sets only OrganizationID.
  2. UpsertSplit upserts on (external_entity_provider_id, external_entity_id); conflict-update (existing) rows don't get their ID populated back, yet are returned in updatedProjects.
  3. syncProjectAssets:306 trusts it: assets[i].ProjectID = project.ID (= uuid.Nil).

Always exactly the zero UUID, only on re-sync — not a race against a real project.

Reproduce:

docker exec -i devguard-postgresql-1 psql -U devguard -d devguard <<'SQL'
BEGIN;
UPDATE assets SET project_id = '00000000-0000-0000-0000-000000000000'
 WHERE id = (SELECT id FROM assets LIMIT 1);
ROLLBACK;
SQL
# => ERROR: ... violates foreign key constraint "fk_projects_assets"
#    DETAIL: Key (project_id)=(00000000-...0000) is not present in table "projects".

App-level: configure an external provider and run the project sync twice.

Fix: populate IDs for updated projects in UpsertSplit (re-select by external keys, map id back); guard syncProjectAssets to skip when project.ID == uuid.Nil.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions