Skip to content

fix: keep valid tags when a bulk upsert hits a bad record #134

Description

@jvsena42

Found while wiring hardware-wallet tag backup on Android (synonymdev/bitkit-android#1163, follow-up to #113). Verified against v0.5.5; reproduced on regtest with the bitkit-docker Trezor emulator.

Problem

upsert_tags opens a single transaction and returns Err as soon as any one record fails, so one unusable tag discards every other tag in the same call.

That matters because the apps restore activities, tags and closed channels together. On Android a single tag whose parent activity did not exist produced:

Failed to restore activity backup [errorDetails=Failed to insert tag: FOREIGN KEY constraint failed]

The whole category was lost — activities and closed channels included, not just the offending tag. Measured on device, activity_tags went 1 to 0 and closed channels were skipped entirely.

The apps can and should isolate their own calls, and Android is doing that separately. But the batch semantics still let one bad row destroy an arbitrary amount of good data, and every consumer otherwise has to write a per-record loop purely to get resilience.

Requested change

Persist the records that can be written and report the rest, rather than failing the batch — for example returning { inserted, skipped[] }.

Acceptance criteria

  • A bulk tag upsert containing one unusable record still persists the remaining records.
  • The caller can tell which records were skipped and why.
  • Tests cover a mixed batch of valid and unusable records.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions