From c75e0ff1abd6d59b8829f368cdcccfb361985406 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 7 Jul 2026 00:09:44 +0000 Subject: [PATCH] fix(cli): don't log benign UNIQUE-constraint dups as store failures MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The SQLite backend raises a catchable UNIQUE-constraint exception when an event is a duplicate id or an older/duplicate replaceable (kind 0/3/10000- 19999) — which the outbox model produces constantly, since each user's replaceable is fetched from several of their write relays. verifyAndStore was logging every one as `[cli] store insert failed`, so a full-network GrapeRank crawl emitted ~294k spurious error lines. The store is behaving correctly (its partial unique index + trigger keep the newest version and reject stale copies); the FS backend simply no-ops on the same duplicates. Suppress UNIQUE-constraint rejections (normal dedup) while still surfacing genuine persistence failures (I/O, full disk, corruption). Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01RWk2ZMrGBSr4WenKgwqmbB --- .../kotlin/com/vitorpamplona/amethyst/cli/Context.kt | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/Context.kt b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/Context.kt index 2e6b4dcccd..ba8c0befea 100644 --- a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/Context.kt +++ b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/Context.kt @@ -559,7 +559,17 @@ class Context( try { store.insert(event) } catch (t: Throwable) { - System.err.println("[cli] store insert failed for ${event.id.take(8)}: ${t.message}") + // A UNIQUE-constraint rejection is normal, not a failure: the + // store already holds this id, or a newer version of a + // replaceable (kind 0/3/10000-19999). The outbox model routinely + // delivers the same event from several of a user's write relays, + // so a crawl produces these by the hundred-thousand. Only surface + // genuine persistence failures (I/O, full disk, corruption). The + // FS backend no-ops on such duplicates; this keeps the SQLite + // backend just as quiet. + if (t.message?.contains("UNIQUE constraint", ignoreCase = true) != true) { + System.err.println("[cli] store insert failed for ${event.id.take(8)}: ${t.message}") + } } return true }