mapDataError has no DUPLICATE_RECORD arm: the engine's insert conflict envelope reaches the wire through the generic passthrough, dropping the field key and the user-facing conflict sentence #14389

Description

@os-musk

Found while implementing #14095 (the ObjectQL half of the 2026-09-01 unique-violation ruling). The engine change is correct and lands on its own; this is the REST-side half of the same condition, in domain:cli territory, filed rather than ridden on that PR.

What changes, and where

Since #14095engine.insert answers a driver unique violation with an ADR-0112 envelope: code: 'DUPLICATE_RECORD', status: 409, the driver error whole on cause, and field when uniqueViolationColumn determinably named the conflicting column.

classifyDataError (packages/rest/src/error-response.ts) reaches the declared-status passthrough arm first, because the envelope declares a status. That arm returns { status, body: { error, ...thrownCodeFields(error, status), object } } — it ships no structured fields of its own. The dedicated isUniqueViolationError arm further down, which builds 409 UNIQUE_VIOLATIONwith a field key, is never reached for an insert conflict any more.

Measured, end to end

Real engine, real drivers, the real mapDataError. AFTER is the envelope; BEFORE is the same conflict's raw driver error handed to the same boundary:

driverindexstatuscodefield on the body
driver-sqlite-wasmsingle column409 → 409UNIQUE_VIOLATIONDUPLICATE_RECORDemailabsent
driver-sqlite-wasmcomposite409 → 409UNIQUE_VIOLATIONDUPLICATE_RECORDabsent → absent (composite names none, by contract)
driver-memorysingle column409 → 409UNIQUE_VIOLATIONDUPLICATE_RECORDabsent → absent
driver-memorycomposite409 → 409UNIQUE_VIOLATIONDUPLICATE_RECORDabsent → absent

So: the status is unaffected — the passthrough honours the declared 409 on every driver, which is the good half. Two things do move:

  1. The field key is gone on the dialects that name a column. That key is what an import UI or a Console form highlights ("A record with this email already exists"), and it is the whole point of import-runner's sanitizeRowError keeps its own three-dialect unique regexes — deferred from #6250 to avoid a merge race with #4633 #6544 / REST: the UNIQUE_VIOLATION 409 message is hard-coded English and carries no field — and it is less informative than the bulk path's own message for the same constraint #7821.
  2. The sentence changes from A record with this email already exists to the engine's own Duplicate record refused on 'duly_note': a unique constraint on 'email' already holds this value. No record was written. Accurate, but it is the platform's sentence, not the one the 409 arm curated for an end user.

For driver-memory the change is an improvement in one respect: that driver's own refusal already declared status: 409, so it ALREADY took the passthrough, and its raw message — which echoes the offending values as JSON (a record with the values {"email":"a@b.example"} already exists) — was reaching the client. The envelope replaces it with a sentence carrying no values.

The shape of the fix

A dedicated DUPLICATE_RECORD arm in classifyDataError, placed with the other structured 409s (DELETE_RESTRICTED, CONCURRENT_UPDATE) ahead of the declared-status passthrough — that placement already exists in the file for exactly this reason ("Surfaced FIRST so the structured fields survive the generic catch-alls"). The envelope carries everything such an arm needs: object, field, developerMessage, and cause.

Open questions for whoever takes it, both wire-contract decisions rather than mechanics:

  • Which code should the wire speakDUPLICATE_RECORD (what the producer now declares) or UNIQUE_VIOLATION (what clients see today)? Both are registered. The ADR-0112 rule is that the producer names the condition, which argues for the former; back-compatibility argues for the latter, and there is a third option where the arm keeps UNIQUE_VIOLATION on the wire and puts the producer's spelling in declaredCode.
  • Which sentence — the engine's, or the arm's curated end-user wording plus developerMessage beside it (the DELETE_RESTRICTED split).

Not a regression in the importer

Measured separately: the import row report READS err.message and err.code (toFailedResultsanitizeRowError). Its code improves from a dialect token (SQLITE_CONSTRAINT_UNIQUE, 11000) to DUPLICATE_RECORD, and the message is the engine's sentence, which the SQL backstop passes through unchanged (it names no statement). No fix owed there.


Triage housekeeping (R+98): the Blocked-by: #14095 line has been removed from this body. #14095 closed as completed on 2026-09-02T06:52Z via PR #14405 — the envelope this card reacts to is on main now, so the line was inert and misrepresented the card as gated. This card is pm:dispatched with PR #14544 open against it, which is the live state; nothing else changes.

Generated by Claude Code

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingdomain:clipriority:p1High: required for production / M2

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

    , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
     blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
    }
    } catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
    })();
    (function(){
    try {
    var __m = "github.com";
    var __re = new RegExp('^' + "github\\.com" + '
    
    Skip to content

    mapDataError has no DUPLICATE_RECORD arm: the engine's insert conflict envelope reaches the wire through the generic passthrough, dropping the field key and the user-facing conflict sentence #14389

    Description

    @os-musk

    Found while implementing #14095 (the ObjectQL half of the 2026-09-01 unique-violation ruling). The engine change is correct and lands on its own; this is the REST-side half of the same condition, in domain:cli territory, filed rather than ridden on that PR.

    What changes, and where

    Since #14095engine.insert answers a driver unique violation with an ADR-0112 envelope: code: 'DUPLICATE_RECORD', status: 409, the driver error whole on cause, and field when uniqueViolationColumn determinably named the conflicting column.

    classifyDataError (packages/rest/src/error-response.ts) reaches the declared-status passthrough arm first, because the envelope declares a status. That arm returns { status, body: { error, ...thrownCodeFields(error, status), object } } — it ships no structured fields of its own. The dedicated isUniqueViolationError arm further down, which builds 409 UNIQUE_VIOLATIONwith a field key, is never reached for an insert conflict any more.

    Measured, end to end

    Real engine, real drivers, the real mapDataError. AFTER is the envelope; BEFORE is the same conflict's raw driver error handed to the same boundary:

    driverindexstatuscodefield on the body
    driver-sqlite-wasmsingle column409 → 409UNIQUE_VIOLATIONDUPLICATE_RECORDemailabsent
    driver-sqlite-wasmcomposite409 → 409UNIQUE_VIOLATIONDUPLICATE_RECORDabsent → absent (composite names none, by contract)
    driver-memorysingle column409 → 409UNIQUE_VIOLATIONDUPLICATE_RECORDabsent → absent
    driver-memorycomposite409 → 409UNIQUE_VIOLATIONDUPLICATE_RECORDabsent → absent

    So: the status is unaffected — the passthrough honours the declared 409 on every driver, which is the good half. Two things do move:

    1. The field key is gone on the dialects that name a column. That key is what an import UI or a Console form highlights ("A record with this email already exists"), and it is the whole point of import-runner's sanitizeRowError keeps its own three-dialect unique regexes — deferred from #6250 to avoid a merge race with #4633 #6544 / REST: the UNIQUE_VIOLATION 409 message is hard-coded English and carries no field — and it is less informative than the bulk path's own message for the same constraint #7821.
    2. The sentence changes from A record with this email already exists to the engine's own Duplicate record refused on 'duly_note': a unique constraint on 'email' already holds this value. No record was written. Accurate, but it is the platform's sentence, not the one the 409 arm curated for an end user.

    For driver-memory the change is an improvement in one respect: that driver's own refusal already declared status: 409, so it ALREADY took the passthrough, and its raw message — which echoes the offending values as JSON (a record with the values {"email":"a@b.example"} already exists) — was reaching the client. The envelope replaces it with a sentence carrying no values.

    The shape of the fix

    A dedicated DUPLICATE_RECORD arm in classifyDataError, placed with the other structured 409s (DELETE_RESTRICTED, CONCURRENT_UPDATE) ahead of the declared-status passthrough — that placement already exists in the file for exactly this reason ("Surfaced FIRST so the structured fields survive the generic catch-alls"). The envelope carries everything such an arm needs: object, field, developerMessage, and cause.

    Open questions for whoever takes it, both wire-contract decisions rather than mechanics:

    • Which code should the wire speakDUPLICATE_RECORD (what the producer now declares) or UNIQUE_VIOLATION (what clients see today)? Both are registered. The ADR-0112 rule is that the producer names the condition, which argues for the former; back-compatibility argues for the latter, and there is a third option where the arm keeps UNIQUE_VIOLATION on the wire and puts the producer's spelling in declaredCode.
    • Which sentence — the engine's, or the arm's curated end-user wording plus developerMessage beside it (the DELETE_RESTRICTED split).

    Not a regression in the importer

    Measured separately: the import row report READS err.message and err.code (toFailedResultsanitizeRowError). Its code improves from a dialect token (SQLITE_CONSTRAINT_UNIQUE, 11000) to DUPLICATE_RECORD, and the message is the engine's sentence, which the SQL backstop passes through unchanged (it names no statement). No fix owed there.


    Triage housekeeping (R+98): the Blocked-by: #14095 line has been removed from this body. #14095 closed as completed on 2026-09-02T06:52Z via PR #14405 — the envelope this card reacts to is on main now, so the line was inert and misrepresented the card as gated. This card is pm:dispatched with PR #14544 open against it, which is the live state; nothing else changes.

    Generated by Claude Code

    Metadata

    Metadata

    Assignees

    Labels

    bugSomething isn't workingdomain:clipriority:p1High: required for production / M2

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
      Skip to content

      mapDataError has no DUPLICATE_RECORD arm: the engine's insert conflict envelope reaches the wire through the generic passthrough, dropping the field key and the user-facing conflict sentence #14389

      Description

      @os-musk

      Found while implementing #14095 (the ObjectQL half of the 2026-09-01 unique-violation ruling). The engine change is correct and lands on its own; this is the REST-side half of the same condition, in domain:cli territory, filed rather than ridden on that PR.

      What changes, and where

      Since #14095engine.insert answers a driver unique violation with an ADR-0112 envelope: code: 'DUPLICATE_RECORD', status: 409, the driver error whole on cause, and field when uniqueViolationColumn determinably named the conflicting column.

      classifyDataError (packages/rest/src/error-response.ts) reaches the declared-status passthrough arm first, because the envelope declares a status. That arm returns { status, body: { error, ...thrownCodeFields(error, status), object } } — it ships no structured fields of its own. The dedicated isUniqueViolationError arm further down, which builds 409 UNIQUE_VIOLATIONwith a field key, is never reached for an insert conflict any more.

      Measured, end to end

      Real engine, real drivers, the real mapDataError. AFTER is the envelope; BEFORE is the same conflict's raw driver error handed to the same boundary:

      driverindexstatuscodefield on the body
      driver-sqlite-wasmsingle column409 → 409UNIQUE_VIOLATIONDUPLICATE_RECORDemailabsent
      driver-sqlite-wasmcomposite409 → 409UNIQUE_VIOLATIONDUPLICATE_RECORDabsent → absent (composite names none, by contract)
      driver-memorysingle column409 → 409UNIQUE_VIOLATIONDUPLICATE_RECORDabsent → absent
      driver-memorycomposite409 → 409UNIQUE_VIOLATIONDUPLICATE_RECORDabsent → absent

      So: the status is unaffected — the passthrough honours the declared 409 on every driver, which is the good half. Two things do move:

      1. The field key is gone on the dialects that name a column. That key is what an import UI or a Console form highlights ("A record with this email already exists"), and it is the whole point of import-runner's sanitizeRowError keeps its own three-dialect unique regexes — deferred from #6250 to avoid a merge race with #4633 #6544 / REST: the UNIQUE_VIOLATION 409 message is hard-coded English and carries no field — and it is less informative than the bulk path's own message for the same constraint #7821.
      2. The sentence changes from A record with this email already exists to the engine's own Duplicate record refused on 'duly_note': a unique constraint on 'email' already holds this value. No record was written. Accurate, but it is the platform's sentence, not the one the 409 arm curated for an end user.

      For driver-memory the change is an improvement in one respect: that driver's own refusal already declared status: 409, so it ALREADY took the passthrough, and its raw message — which echoes the offending values as JSON (a record with the values {"email":"a@b.example"} already exists) — was reaching the client. The envelope replaces it with a sentence carrying no values.

      The shape of the fix

      A dedicated DUPLICATE_RECORD arm in classifyDataError, placed with the other structured 409s (DELETE_RESTRICTED, CONCURRENT_UPDATE) ahead of the declared-status passthrough — that placement already exists in the file for exactly this reason ("Surfaced FIRST so the structured fields survive the generic catch-alls"). The envelope carries everything such an arm needs: object, field, developerMessage, and cause.

      Open questions for whoever takes it, both wire-contract decisions rather than mechanics:

      • Which code should the wire speakDUPLICATE_RECORD (what the producer now declares) or UNIQUE_VIOLATION (what clients see today)? Both are registered. The ADR-0112 rule is that the producer names the condition, which argues for the former; back-compatibility argues for the latter, and there is a third option where the arm keeps UNIQUE_VIOLATION on the wire and puts the producer's spelling in declaredCode.
      • Which sentence — the engine's, or the arm's curated end-user wording plus developerMessage beside it (the DELETE_RESTRICTED split).

      Not a regression in the importer

      Measured separately: the import row report READS err.message and err.code (toFailedResultsanitizeRowError). Its code improves from a dialect token (SQLITE_CONSTRAINT_UNIQUE, 11000) to DUPLICATE_RECORD, and the message is the engine's sentence, which the SQL backstop passes through unchanged (it names no statement). No fix owed there.


      Triage housekeeping (R+98): the Blocked-by: #14095 line has been removed from this body. #14095 closed as completed on 2026-09-02T06:52Z via PR #14405 — the envelope this card reacts to is on main now, so the line was inert and misrepresented the card as gated. This card is pm:dispatched with PR #14544 open against it, which is the live state; nothing else changes.

      Generated by Claude Code

      Metadata

      Metadata

      Assignees

      Labels

      bugSomething isn't workingdomain:clipriority:p1High: required for production / M2

      Type

      Projects

      No projects

        Milestone

        No milestone

        Relationships

        None yet

        Development

        No branches or pull requests

        Issue actions

        , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
        Skip to content

        mapDataError has no DUPLICATE_RECORD arm: the engine's insert conflict envelope reaches the wire through the generic passthrough, dropping the field key and the user-facing conflict sentence #14389

        Description

        @os-musk

        Found while implementing #14095 (the ObjectQL half of the 2026-09-01 unique-violation ruling). The engine change is correct and lands on its own; this is the REST-side half of the same condition, in domain:cli territory, filed rather than ridden on that PR.

        What changes, and where

        Since #14095engine.insert answers a driver unique violation with an ADR-0112 envelope: code: 'DUPLICATE_RECORD', status: 409, the driver error whole on cause, and field when uniqueViolationColumn determinably named the conflicting column.

        classifyDataError (packages/rest/src/error-response.ts) reaches the declared-status passthrough arm first, because the envelope declares a status. That arm returns { status, body: { error, ...thrownCodeFields(error, status), object } } — it ships no structured fields of its own. The dedicated isUniqueViolationError arm further down, which builds 409 UNIQUE_VIOLATIONwith a field key, is never reached for an insert conflict any more.

        Measured, end to end

        Real engine, real drivers, the real mapDataError. AFTER is the envelope; BEFORE is the same conflict's raw driver error handed to the same boundary:

        driverindexstatuscodefield on the body
        driver-sqlite-wasmsingle column409 → 409UNIQUE_VIOLATIONDUPLICATE_RECORDemailabsent
        driver-sqlite-wasmcomposite409 → 409UNIQUE_VIOLATIONDUPLICATE_RECORDabsent → absent (composite names none, by contract)
        driver-memorysingle column409 → 409UNIQUE_VIOLATIONDUPLICATE_RECORDabsent → absent
        driver-memorycomposite409 → 409UNIQUE_VIOLATIONDUPLICATE_RECORDabsent → absent

        So: the status is unaffected — the passthrough honours the declared 409 on every driver, which is the good half. Two things do move:

        1. The field key is gone on the dialects that name a column. That key is what an import UI or a Console form highlights ("A record with this email already exists"), and it is the whole point of import-runner's sanitizeRowError keeps its own three-dialect unique regexes — deferred from #6250 to avoid a merge race with #4633 #6544 / REST: the UNIQUE_VIOLATION 409 message is hard-coded English and carries no field — and it is less informative than the bulk path's own message for the same constraint #7821.
        2. The sentence changes from A record with this email already exists to the engine's own Duplicate record refused on 'duly_note': a unique constraint on 'email' already holds this value. No record was written. Accurate, but it is the platform's sentence, not the one the 409 arm curated for an end user.

        For driver-memory the change is an improvement in one respect: that driver's own refusal already declared status: 409, so it ALREADY took the passthrough, and its raw message — which echoes the offending values as JSON (a record with the values {"email":"a@b.example"} already exists) — was reaching the client. The envelope replaces it with a sentence carrying no values.

        The shape of the fix

        A dedicated DUPLICATE_RECORD arm in classifyDataError, placed with the other structured 409s (DELETE_RESTRICTED, CONCURRENT_UPDATE) ahead of the declared-status passthrough — that placement already exists in the file for exactly this reason ("Surfaced FIRST so the structured fields survive the generic catch-alls"). The envelope carries everything such an arm needs: object, field, developerMessage, and cause.

        Open questions for whoever takes it, both wire-contract decisions rather than mechanics:

        • Which code should the wire speakDUPLICATE_RECORD (what the producer now declares) or UNIQUE_VIOLATION (what clients see today)? Both are registered. The ADR-0112 rule is that the producer names the condition, which argues for the former; back-compatibility argues for the latter, and there is a third option where the arm keeps UNIQUE_VIOLATION on the wire and puts the producer's spelling in declaredCode.
        • Which sentence — the engine's, or the arm's curated end-user wording plus developerMessage beside it (the DELETE_RESTRICTED split).

        Not a regression in the importer

        Measured separately: the import row report READS err.message and err.code (toFailedResultsanitizeRowError). Its code improves from a dialect token (SQLITE_CONSTRAINT_UNIQUE, 11000) to DUPLICATE_RECORD, and the message is the engine's sentence, which the SQL backstop passes through unchanged (it names no statement). No fix owed there.


        Triage housekeeping (R+98): the Blocked-by: #14095 line has been removed from this body. #14095 closed as completed on 2026-09-02T06:52Z via PR #14405 — the envelope this card reacts to is on main now, so the line was inert and misrepresented the card as gated. This card is pm:dispatched with PR #14544 open against it, which is the live state; nothing else changes.

        Generated by Claude Code

        Metadata

        Metadata

        Assignees

        Labels

        bugSomething isn't workingdomain:clipriority:p1High: required for production / M2

        Type

        Projects

        No projects

          Milestone

          No milestone

          Relationships

          None yet

          Development

          No branches or pull requests

          Issue actions

          , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
          Skip to content

          mapDataError has no DUPLICATE_RECORD arm: the engine's insert conflict envelope reaches the wire through the generic passthrough, dropping the field key and the user-facing conflict sentence #14389

          Description

          @os-musk

          Found while implementing #14095 (the ObjectQL half of the 2026-09-01 unique-violation ruling). The engine change is correct and lands on its own; this is the REST-side half of the same condition, in domain:cli territory, filed rather than ridden on that PR.

          What changes, and where

          Since #14095engine.insert answers a driver unique violation with an ADR-0112 envelope: code: 'DUPLICATE_RECORD', status: 409, the driver error whole on cause, and field when uniqueViolationColumn determinably named the conflicting column.

          classifyDataError (packages/rest/src/error-response.ts) reaches the declared-status passthrough arm first, because the envelope declares a status. That arm returns { status, body: { error, ...thrownCodeFields(error, status), object } } — it ships no structured fields of its own. The dedicated isUniqueViolationError arm further down, which builds 409 UNIQUE_VIOLATIONwith a field key, is never reached for an insert conflict any more.

          Measured, end to end

          Real engine, real drivers, the real mapDataError. AFTER is the envelope; BEFORE is the same conflict's raw driver error handed to the same boundary:

          driverindexstatuscodefield on the body
          driver-sqlite-wasmsingle column409 → 409UNIQUE_VIOLATIONDUPLICATE_RECORDemailabsent
          driver-sqlite-wasmcomposite409 → 409UNIQUE_VIOLATIONDUPLICATE_RECORDabsent → absent (composite names none, by contract)
          driver-memorysingle column409 → 409UNIQUE_VIOLATIONDUPLICATE_RECORDabsent → absent
          driver-memorycomposite409 → 409UNIQUE_VIOLATIONDUPLICATE_RECORDabsent → absent

          So: the status is unaffected — the passthrough honours the declared 409 on every driver, which is the good half. Two things do move:

          1. The field key is gone on the dialects that name a column. That key is what an import UI or a Console form highlights ("A record with this email already exists"), and it is the whole point of import-runner's sanitizeRowError keeps its own three-dialect unique regexes — deferred from #6250 to avoid a merge race with #4633 #6544 / REST: the UNIQUE_VIOLATION 409 message is hard-coded English and carries no field — and it is less informative than the bulk path's own message for the same constraint #7821.
          2. The sentence changes from A record with this email already exists to the engine's own Duplicate record refused on 'duly_note': a unique constraint on 'email' already holds this value. No record was written. Accurate, but it is the platform's sentence, not the one the 409 arm curated for an end user.

          For driver-memory the change is an improvement in one respect: that driver's own refusal already declared status: 409, so it ALREADY took the passthrough, and its raw message — which echoes the offending values as JSON (a record with the values {"email":"a@b.example"} already exists) — was reaching the client. The envelope replaces it with a sentence carrying no values.

          The shape of the fix

          A dedicated DUPLICATE_RECORD arm in classifyDataError, placed with the other structured 409s (DELETE_RESTRICTED, CONCURRENT_UPDATE) ahead of the declared-status passthrough — that placement already exists in the file for exactly this reason ("Surfaced FIRST so the structured fields survive the generic catch-alls"). The envelope carries everything such an arm needs: object, field, developerMessage, and cause.

          Open questions for whoever takes it, both wire-contract decisions rather than mechanics:

          • Which code should the wire speakDUPLICATE_RECORD (what the producer now declares) or UNIQUE_VIOLATION (what clients see today)? Both are registered. The ADR-0112 rule is that the producer names the condition, which argues for the former; back-compatibility argues for the latter, and there is a third option where the arm keeps UNIQUE_VIOLATION on the wire and puts the producer's spelling in declaredCode.
          • Which sentence — the engine's, or the arm's curated end-user wording plus developerMessage beside it (the DELETE_RESTRICTED split).

          Not a regression in the importer

          Measured separately: the import row report READS err.message and err.code (toFailedResultsanitizeRowError). Its code improves from a dialect token (SQLITE_CONSTRAINT_UNIQUE, 11000) to DUPLICATE_RECORD, and the message is the engine's sentence, which the SQL backstop passes through unchanged (it names no statement). No fix owed there.


          Triage housekeeping (R+98): the Blocked-by: #14095 line has been removed from this body. #14095 closed as completed on 2026-09-02T06:52Z via PR #14405 — the envelope this card reacts to is on main now, so the line was inert and misrepresented the card as gated. This card is pm:dispatched with PR #14544 open against it, which is the live state; nothing else changes.

          Generated by Claude Code

          Metadata

          Metadata

          Assignees

          Labels

          bugSomething isn't workingdomain:clipriority:p1High: required for production / M2

          Type

          Projects

          No projects

            Milestone

            No milestone

            Relationships

            None yet

            Development

            No branches or pull requests

            Issue actions

            , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
            Skip to content

            mapDataError has no DUPLICATE_RECORD arm: the engine's insert conflict envelope reaches the wire through the generic passthrough, dropping the field key and the user-facing conflict sentence #14389

            Description

            @os-musk

            Found while implementing #14095 (the ObjectQL half of the 2026-09-01 unique-violation ruling). The engine change is correct and lands on its own; this is the REST-side half of the same condition, in domain:cli territory, filed rather than ridden on that PR.

            What changes, and where

            Since #14095engine.insert answers a driver unique violation with an ADR-0112 envelope: code: 'DUPLICATE_RECORD', status: 409, the driver error whole on cause, and field when uniqueViolationColumn determinably named the conflicting column.

            classifyDataError (packages/rest/src/error-response.ts) reaches the declared-status passthrough arm first, because the envelope declares a status. That arm returns { status, body: { error, ...thrownCodeFields(error, status), object } } — it ships no structured fields of its own. The dedicated isUniqueViolationError arm further down, which builds 409 UNIQUE_VIOLATIONwith a field key, is never reached for an insert conflict any more.

            Measured, end to end

            Real engine, real drivers, the real mapDataError. AFTER is the envelope; BEFORE is the same conflict's raw driver error handed to the same boundary:

            driverindexstatuscodefield on the body
            driver-sqlite-wasmsingle column409 → 409UNIQUE_VIOLATIONDUPLICATE_RECORDemailabsent
            driver-sqlite-wasmcomposite409 → 409UNIQUE_VIOLATIONDUPLICATE_RECORDabsent → absent (composite names none, by contract)
            driver-memorysingle column409 → 409UNIQUE_VIOLATIONDUPLICATE_RECORDabsent → absent
            driver-memorycomposite409 → 409UNIQUE_VIOLATIONDUPLICATE_RECORDabsent → absent

            So: the status is unaffected — the passthrough honours the declared 409 on every driver, which is the good half. Two things do move:

            1. The field key is gone on the dialects that name a column. That key is what an import UI or a Console form highlights ("A record with this email already exists"), and it is the whole point of import-runner's sanitizeRowError keeps its own three-dialect unique regexes — deferred from #6250 to avoid a merge race with #4633 #6544 / REST: the UNIQUE_VIOLATION 409 message is hard-coded English and carries no field — and it is less informative than the bulk path's own message for the same constraint #7821.
            2. The sentence changes from A record with this email already exists to the engine's own Duplicate record refused on 'duly_note': a unique constraint on 'email' already holds this value. No record was written. Accurate, but it is the platform's sentence, not the one the 409 arm curated for an end user.

            For driver-memory the change is an improvement in one respect: that driver's own refusal already declared status: 409, so it ALREADY took the passthrough, and its raw message — which echoes the offending values as JSON (a record with the values {"email":"a@b.example"} already exists) — was reaching the client. The envelope replaces it with a sentence carrying no values.

            The shape of the fix

            A dedicated DUPLICATE_RECORD arm in classifyDataError, placed with the other structured 409s (DELETE_RESTRICTED, CONCURRENT_UPDATE) ahead of the declared-status passthrough — that placement already exists in the file for exactly this reason ("Surfaced FIRST so the structured fields survive the generic catch-alls"). The envelope carries everything such an arm needs: object, field, developerMessage, and cause.

            Open questions for whoever takes it, both wire-contract decisions rather than mechanics:

            • Which code should the wire speakDUPLICATE_RECORD (what the producer now declares) or UNIQUE_VIOLATION (what clients see today)? Both are registered. The ADR-0112 rule is that the producer names the condition, which argues for the former; back-compatibility argues for the latter, and there is a third option where the arm keeps UNIQUE_VIOLATION on the wire and puts the producer's spelling in declaredCode.
            • Which sentence — the engine's, or the arm's curated end-user wording plus developerMessage beside it (the DELETE_RESTRICTED split).

            Not a regression in the importer

            Measured separately: the import row report READS err.message and err.code (toFailedResultsanitizeRowError). Its code improves from a dialect token (SQLITE_CONSTRAINT_UNIQUE, 11000) to DUPLICATE_RECORD, and the message is the engine's sentence, which the SQL backstop passes through unchanged (it names no statement). No fix owed there.


            Triage housekeeping (R+98): the Blocked-by: #14095 line has been removed from this body. #14095 closed as completed on 2026-09-02T06:52Z via PR #14405 — the envelope this card reacts to is on main now, so the line was inert and misrepresented the card as gated. This card is pm:dispatched with PR #14544 open against it, which is the live state; nothing else changes.

            Generated by Claude Code

            Metadata

            Metadata

            Assignees

            Labels

            bugSomething isn't workingdomain:clipriority:p1High: required for production / M2

            Type

            Projects

            No projects

              Milestone

              No milestone

              Relationships

              None yet

              Development

              No branches or pull requests

              Issue actions

              , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
              Skip to content

              mapDataError has no DUPLICATE_RECORD arm: the engine's insert conflict envelope reaches the wire through the generic passthrough, dropping the field key and the user-facing conflict sentence #14389

              Description

              @os-musk

              Found while implementing #14095 (the ObjectQL half of the 2026-09-01 unique-violation ruling). The engine change is correct and lands on its own; this is the REST-side half of the same condition, in domain:cli territory, filed rather than ridden on that PR.

              What changes, and where

              Since #14095engine.insert answers a driver unique violation with an ADR-0112 envelope: code: 'DUPLICATE_RECORD', status: 409, the driver error whole on cause, and field when uniqueViolationColumn determinably named the conflicting column.

              classifyDataError (packages/rest/src/error-response.ts) reaches the declared-status passthrough arm first, because the envelope declares a status. That arm returns { status, body: { error, ...thrownCodeFields(error, status), object } } — it ships no structured fields of its own. The dedicated isUniqueViolationError arm further down, which builds 409 UNIQUE_VIOLATIONwith a field key, is never reached for an insert conflict any more.

              Measured, end to end

              Real engine, real drivers, the real mapDataError. AFTER is the envelope; BEFORE is the same conflict's raw driver error handed to the same boundary:

              driverindexstatuscodefield on the body
              driver-sqlite-wasmsingle column409 → 409UNIQUE_VIOLATIONDUPLICATE_RECORDemailabsent
              driver-sqlite-wasmcomposite409 → 409UNIQUE_VIOLATIONDUPLICATE_RECORDabsent → absent (composite names none, by contract)
              driver-memorysingle column409 → 409UNIQUE_VIOLATIONDUPLICATE_RECORDabsent → absent
              driver-memorycomposite409 → 409UNIQUE_VIOLATIONDUPLICATE_RECORDabsent → absent

              So: the status is unaffected — the passthrough honours the declared 409 on every driver, which is the good half. Two things do move:

              1. The field key is gone on the dialects that name a column. That key is what an import UI or a Console form highlights ("A record with this email already exists"), and it is the whole point of import-runner's sanitizeRowError keeps its own three-dialect unique regexes — deferred from #6250 to avoid a merge race with #4633 #6544 / REST: the UNIQUE_VIOLATION 409 message is hard-coded English and carries no field — and it is less informative than the bulk path's own message for the same constraint #7821.
              2. The sentence changes from A record with this email already exists to the engine's own Duplicate record refused on 'duly_note': a unique constraint on 'email' already holds this value. No record was written. Accurate, but it is the platform's sentence, not the one the 409 arm curated for an end user.

              For driver-memory the change is an improvement in one respect: that driver's own refusal already declared status: 409, so it ALREADY took the passthrough, and its raw message — which echoes the offending values as JSON (a record with the values {"email":"a@b.example"} already exists) — was reaching the client. The envelope replaces it with a sentence carrying no values.

              The shape of the fix

              A dedicated DUPLICATE_RECORD arm in classifyDataError, placed with the other structured 409s (DELETE_RESTRICTED, CONCURRENT_UPDATE) ahead of the declared-status passthrough — that placement already exists in the file for exactly this reason ("Surfaced FIRST so the structured fields survive the generic catch-alls"). The envelope carries everything such an arm needs: object, field, developerMessage, and cause.

              Open questions for whoever takes it, both wire-contract decisions rather than mechanics:

              • Which code should the wire speakDUPLICATE_RECORD (what the producer now declares) or UNIQUE_VIOLATION (what clients see today)? Both are registered. The ADR-0112 rule is that the producer names the condition, which argues for the former; back-compatibility argues for the latter, and there is a third option where the arm keeps UNIQUE_VIOLATION on the wire and puts the producer's spelling in declaredCode.
              • Which sentence — the engine's, or the arm's curated end-user wording plus developerMessage beside it (the DELETE_RESTRICTED split).

              Not a regression in the importer

              Measured separately: the import row report READS err.message and err.code (toFailedResultsanitizeRowError). Its code improves from a dialect token (SQLITE_CONSTRAINT_UNIQUE, 11000) to DUPLICATE_RECORD, and the message is the engine's sentence, which the SQL backstop passes through unchanged (it names no statement). No fix owed there.


              Triage housekeeping (R+98): the Blocked-by: #14095 line has been removed from this body. #14095 closed as completed on 2026-09-02T06:52Z via PR #14405 — the envelope this card reacts to is on main now, so the line was inert and misrepresented the card as gated. This card is pm:dispatched with PR #14544 open against it, which is the live state; nothing else changes.

              Generated by Claude Code

              Metadata

              Metadata

              Assignees

              Labels

              bugSomething isn't workingdomain:clipriority:p1High: required for production / M2

              Type

              Projects

              No projects

                Milestone

                No milestone

                Relationships

                None yet

                Development

                No branches or pull requests

                Issue actions

                , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
                Skip to content

                mapDataError has no DUPLICATE_RECORD arm: the engine's insert conflict envelope reaches the wire through the generic passthrough, dropping the field key and the user-facing conflict sentence #14389

                Description

                @os-musk

                Found while implementing #14095 (the ObjectQL half of the 2026-09-01 unique-violation ruling). The engine change is correct and lands on its own; this is the REST-side half of the same condition, in domain:cli territory, filed rather than ridden on that PR.

                What changes, and where

                Since #14095engine.insert answers a driver unique violation with an ADR-0112 envelope: code: 'DUPLICATE_RECORD', status: 409, the driver error whole on cause, and field when uniqueViolationColumn determinably named the conflicting column.

                classifyDataError (packages/rest/src/error-response.ts) reaches the declared-status passthrough arm first, because the envelope declares a status. That arm returns { status, body: { error, ...thrownCodeFields(error, status), object } } — it ships no structured fields of its own. The dedicated isUniqueViolationError arm further down, which builds 409 UNIQUE_VIOLATIONwith a field key, is never reached for an insert conflict any more.

                Measured, end to end

                Real engine, real drivers, the real mapDataError. AFTER is the envelope; BEFORE is the same conflict's raw driver error handed to the same boundary:

                driverindexstatuscodefield on the body
                driver-sqlite-wasmsingle column409 → 409UNIQUE_VIOLATIONDUPLICATE_RECORDemailabsent
                driver-sqlite-wasmcomposite409 → 409UNIQUE_VIOLATIONDUPLICATE_RECORDabsent → absent (composite names none, by contract)
                driver-memorysingle column409 → 409UNIQUE_VIOLATIONDUPLICATE_RECORDabsent → absent
                driver-memorycomposite409 → 409UNIQUE_VIOLATIONDUPLICATE_RECORDabsent → absent

                So: the status is unaffected — the passthrough honours the declared 409 on every driver, which is the good half. Two things do move:

                1. The field key is gone on the dialects that name a column. That key is what an import UI or a Console form highlights ("A record with this email already exists"), and it is the whole point of import-runner's sanitizeRowError keeps its own three-dialect unique regexes — deferred from #6250 to avoid a merge race with #4633 #6544 / REST: the UNIQUE_VIOLATION 409 message is hard-coded English and carries no field — and it is less informative than the bulk path's own message for the same constraint #7821.
                2. The sentence changes from A record with this email already exists to the engine's own Duplicate record refused on 'duly_note': a unique constraint on 'email' already holds this value. No record was written. Accurate, but it is the platform's sentence, not the one the 409 arm curated for an end user.

                For driver-memory the change is an improvement in one respect: that driver's own refusal already declared status: 409, so it ALREADY took the passthrough, and its raw message — which echoes the offending values as JSON (a record with the values {"email":"a@b.example"} already exists) — was reaching the client. The envelope replaces it with a sentence carrying no values.

                The shape of the fix

                A dedicated DUPLICATE_RECORD arm in classifyDataError, placed with the other structured 409s (DELETE_RESTRICTED, CONCURRENT_UPDATE) ahead of the declared-status passthrough — that placement already exists in the file for exactly this reason ("Surfaced FIRST so the structured fields survive the generic catch-alls"). The envelope carries everything such an arm needs: object, field, developerMessage, and cause.

                Open questions for whoever takes it, both wire-contract decisions rather than mechanics:

                • Which code should the wire speakDUPLICATE_RECORD (what the producer now declares) or UNIQUE_VIOLATION (what clients see today)? Both are registered. The ADR-0112 rule is that the producer names the condition, which argues for the former; back-compatibility argues for the latter, and there is a third option where the arm keeps UNIQUE_VIOLATION on the wire and puts the producer's spelling in declaredCode.
                • Which sentence — the engine's, or the arm's curated end-user wording plus developerMessage beside it (the DELETE_RESTRICTED split).

                Not a regression in the importer

                Measured separately: the import row report READS err.message and err.code (toFailedResultsanitizeRowError). Its code improves from a dialect token (SQLITE_CONSTRAINT_UNIQUE, 11000) to DUPLICATE_RECORD, and the message is the engine's sentence, which the SQL backstop passes through unchanged (it names no statement). No fix owed there.


                Triage housekeeping (R+98): the Blocked-by: #14095 line has been removed from this body. #14095 closed as completed on 2026-09-02T06:52Z via PR #14405 — the envelope this card reacts to is on main now, so the line was inert and misrepresented the card as gated. This card is pm:dispatched with PR #14544 open against it, which is the live state; nothing else changes.

                Generated by Claude Code

                Metadata

                Metadata

                Assignees

                Labels

                bugSomething isn't workingdomain:clipriority:p1High: required for production / M2

                Type

                Projects

                No projects

                  Milestone

                  No milestone

                  Relationships

                  None yet

                  Development

                  No branches or pull requests

                  Issue actions