engine.update still leaks the raw driver unique-violation error — the same defect one verb over from the insert door, with the whole UPDATE statement as its message #14390

Description

@os-musk

Found while implementing #14095, whose scope was explicitly the INSERT door. Filed rather than widened into that PR.

Measured

Real ObjectQL engine on a real driver-sqlite-wasm store, an object carrying a declared unique index on email. Two rows exist; the second is driven onto the first's value, so the UPDATE violates the index:

{
"threw": true,
"name": "Error",
"code": undefined,"status": undefined,"hasCause": false,
"message": "update `duly_note` set `id` = 'JrzMrU3fJnc5__tV', `email` = 'a@b.example', `updated_at` = '2026-09-02T03:54:04.936Z' where `id` = 'JrzMrU3fJnc5__tV' -"
}

No code, no status, no cause — and the message is the compiled UPDATE statement with its bound values, exactly the shape #14095 measured on the insert side.

Why it matters, and why it is not merely cosmetic

The platform now has ONE contract for this condition on insert and none on update, which is worse than having neither: an application that correctly branches on code === 'DUPLICATE_RECORD' for its create path silently falls through to the generic error branch on its edit path, on every driver. "Renaming a record onto a name someone else already took" is the ordinary form-submission case, and it is the one that stays dialect-coupled.

An application cannot close it locally for the same three reasons the insert card enumerated: branching on SQLITE_CONSTRAINT_UNIQUE couples it to one dialect, the message is a compiled statement, and isUniqueViolationError lives in @objectstack/types, which an application cannot resolve.

The shape of the work

The insert side landed as envelopeUniqueViolation(error, object) from packages/objectql/src/duplicate-record-error.ts, applied at each point a driver error leaves the insert door. The update door needs the same treatment at its own driver-error exits, with the same negative contract (only a recognised unique violation is enveloped; a NOT NULL, a deadlock, a missing table and an unreachable store leave untouched) and the same operator-log rule (the log takes cause, so the driver's diagnosis stays in the line).

Two things the insert card settled that this one has to decide for itself:

  • update can refuse a MULTI-row write. Which row conflicted is a question the insert envelope never had to answer, and the driver's error may not answer it either. The envelope's field half is unaffected (uniqueViolationColumn reads the same channels), but a caller may reasonably want to know it was one of N.
  • upsert is the same door's neighbour and is deliberately excluded here: on some dialects an upsert converts a conflict into a merge, so "a unique violation escaped" means something different there. It deserves its own measurement before any envelope is put on it.

Unassigned and untriaged.


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 reference pattern this card is asked to mirror (envelopeUniqueViolation) is on main now, so the line was inert and misrepresented the card as gated. This card is already pm:dispatched, so nothing else changes.

Generated by Claude Code

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingdomain:enginepriority: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

    engine.update still leaks the raw driver unique-violation error — the same defect one verb over from the insert door, with the whole UPDATE statement as its message #14390

    Description

    @os-musk

    Found while implementing #14095, whose scope was explicitly the INSERT door. Filed rather than widened into that PR.

    Measured

    Real ObjectQL engine on a real driver-sqlite-wasm store, an object carrying a declared unique index on email. Two rows exist; the second is driven onto the first's value, so the UPDATE violates the index:

    {
    "threw": true,
    "name": "Error",
    "code": undefined,"status": undefined,"hasCause": false,
    "message": "update `duly_note` set `id` = 'JrzMrU3fJnc5__tV', `email` = 'a@b.example', `updated_at` = '2026-09-02T03:54:04.936Z' where `id` = 'JrzMrU3fJnc5__tV' -"
    }

    No code, no status, no cause — and the message is the compiled UPDATE statement with its bound values, exactly the shape #14095 measured on the insert side.

    Why it matters, and why it is not merely cosmetic

    The platform now has ONE contract for this condition on insert and none on update, which is worse than having neither: an application that correctly branches on code === 'DUPLICATE_RECORD' for its create path silently falls through to the generic error branch on its edit path, on every driver. "Renaming a record onto a name someone else already took" is the ordinary form-submission case, and it is the one that stays dialect-coupled.

    An application cannot close it locally for the same three reasons the insert card enumerated: branching on SQLITE_CONSTRAINT_UNIQUE couples it to one dialect, the message is a compiled statement, and isUniqueViolationError lives in @objectstack/types, which an application cannot resolve.

    The shape of the work

    The insert side landed as envelopeUniqueViolation(error, object) from packages/objectql/src/duplicate-record-error.ts, applied at each point a driver error leaves the insert door. The update door needs the same treatment at its own driver-error exits, with the same negative contract (only a recognised unique violation is enveloped; a NOT NULL, a deadlock, a missing table and an unreachable store leave untouched) and the same operator-log rule (the log takes cause, so the driver's diagnosis stays in the line).

    Two things the insert card settled that this one has to decide for itself:

    • update can refuse a MULTI-row write. Which row conflicted is a question the insert envelope never had to answer, and the driver's error may not answer it either. The envelope's field half is unaffected (uniqueViolationColumn reads the same channels), but a caller may reasonably want to know it was one of N.
    • upsert is the same door's neighbour and is deliberately excluded here: on some dialects an upsert converts a conflict into a merge, so "a unique violation escaped" means something different there. It deserves its own measurement before any envelope is put on it.

    Unassigned and untriaged.


    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 reference pattern this card is asked to mirror (envelopeUniqueViolation) is on main now, so the line was inert and misrepresented the card as gated. This card is already pm:dispatched, so nothing else changes.

    Generated by Claude Code

    Metadata

    Metadata

    Assignees

    Labels

    bugSomething isn't workingdomain:enginepriority: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

      engine.update still leaks the raw driver unique-violation error — the same defect one verb over from the insert door, with the whole UPDATE statement as its message #14390

      Description

      @os-musk

      Found while implementing #14095, whose scope was explicitly the INSERT door. Filed rather than widened into that PR.

      Measured

      Real ObjectQL engine on a real driver-sqlite-wasm store, an object carrying a declared unique index on email. Two rows exist; the second is driven onto the first's value, so the UPDATE violates the index:

      {
      "threw": true,
      "name": "Error",
      "code": undefined,"status": undefined,"hasCause": false,
      "message": "update `duly_note` set `id` = 'JrzMrU3fJnc5__tV', `email` = 'a@b.example', `updated_at` = '2026-09-02T03:54:04.936Z' where `id` = 'JrzMrU3fJnc5__tV' -"
      }

      No code, no status, no cause — and the message is the compiled UPDATE statement with its bound values, exactly the shape #14095 measured on the insert side.

      Why it matters, and why it is not merely cosmetic

      The platform now has ONE contract for this condition on insert and none on update, which is worse than having neither: an application that correctly branches on code === 'DUPLICATE_RECORD' for its create path silently falls through to the generic error branch on its edit path, on every driver. "Renaming a record onto a name someone else already took" is the ordinary form-submission case, and it is the one that stays dialect-coupled.

      An application cannot close it locally for the same three reasons the insert card enumerated: branching on SQLITE_CONSTRAINT_UNIQUE couples it to one dialect, the message is a compiled statement, and isUniqueViolationError lives in @objectstack/types, which an application cannot resolve.

      The shape of the work

      The insert side landed as envelopeUniqueViolation(error, object) from packages/objectql/src/duplicate-record-error.ts, applied at each point a driver error leaves the insert door. The update door needs the same treatment at its own driver-error exits, with the same negative contract (only a recognised unique violation is enveloped; a NOT NULL, a deadlock, a missing table and an unreachable store leave untouched) and the same operator-log rule (the log takes cause, so the driver's diagnosis stays in the line).

      Two things the insert card settled that this one has to decide for itself:

      • update can refuse a MULTI-row write. Which row conflicted is a question the insert envelope never had to answer, and the driver's error may not answer it either. The envelope's field half is unaffected (uniqueViolationColumn reads the same channels), but a caller may reasonably want to know it was one of N.
      • upsert is the same door's neighbour and is deliberately excluded here: on some dialects an upsert converts a conflict into a merge, so "a unique violation escaped" means something different there. It deserves its own measurement before any envelope is put on it.

      Unassigned and untriaged.


      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 reference pattern this card is asked to mirror (envelopeUniqueViolation) is on main now, so the line was inert and misrepresented the card as gated. This card is already pm:dispatched, so nothing else changes.

      Generated by Claude Code

      Metadata

      Metadata

      Assignees

      Labels

      bugSomething isn't workingdomain:enginepriority: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

        engine.update still leaks the raw driver unique-violation error — the same defect one verb over from the insert door, with the whole UPDATE statement as its message #14390

        Description

        @os-musk

        Found while implementing #14095, whose scope was explicitly the INSERT door. Filed rather than widened into that PR.

        Measured

        Real ObjectQL engine on a real driver-sqlite-wasm store, an object carrying a declared unique index on email. Two rows exist; the second is driven onto the first's value, so the UPDATE violates the index:

        {
        "threw": true,
        "name": "Error",
        "code": undefined,"status": undefined,"hasCause": false,
        "message": "update `duly_note` set `id` = 'JrzMrU3fJnc5__tV', `email` = 'a@b.example', `updated_at` = '2026-09-02T03:54:04.936Z' where `id` = 'JrzMrU3fJnc5__tV' -"
        }

        No code, no status, no cause — and the message is the compiled UPDATE statement with its bound values, exactly the shape #14095 measured on the insert side.

        Why it matters, and why it is not merely cosmetic

        The platform now has ONE contract for this condition on insert and none on update, which is worse than having neither: an application that correctly branches on code === 'DUPLICATE_RECORD' for its create path silently falls through to the generic error branch on its edit path, on every driver. "Renaming a record onto a name someone else already took" is the ordinary form-submission case, and it is the one that stays dialect-coupled.

        An application cannot close it locally for the same three reasons the insert card enumerated: branching on SQLITE_CONSTRAINT_UNIQUE couples it to one dialect, the message is a compiled statement, and isUniqueViolationError lives in @objectstack/types, which an application cannot resolve.

        The shape of the work

        The insert side landed as envelopeUniqueViolation(error, object) from packages/objectql/src/duplicate-record-error.ts, applied at each point a driver error leaves the insert door. The update door needs the same treatment at its own driver-error exits, with the same negative contract (only a recognised unique violation is enveloped; a NOT NULL, a deadlock, a missing table and an unreachable store leave untouched) and the same operator-log rule (the log takes cause, so the driver's diagnosis stays in the line).

        Two things the insert card settled that this one has to decide for itself:

        • update can refuse a MULTI-row write. Which row conflicted is a question the insert envelope never had to answer, and the driver's error may not answer it either. The envelope's field half is unaffected (uniqueViolationColumn reads the same channels), but a caller may reasonably want to know it was one of N.
        • upsert is the same door's neighbour and is deliberately excluded here: on some dialects an upsert converts a conflict into a merge, so "a unique violation escaped" means something different there. It deserves its own measurement before any envelope is put on it.

        Unassigned and untriaged.


        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 reference pattern this card is asked to mirror (envelopeUniqueViolation) is on main now, so the line was inert and misrepresented the card as gated. This card is already pm:dispatched, so nothing else changes.

        Generated by Claude Code

        Metadata

        Metadata

        Assignees

        Labels

        bugSomething isn't workingdomain:enginepriority: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

          engine.update still leaks the raw driver unique-violation error — the same defect one verb over from the insert door, with the whole UPDATE statement as its message #14390

          Description

          @os-musk

          Found while implementing #14095, whose scope was explicitly the INSERT door. Filed rather than widened into that PR.

          Measured

          Real ObjectQL engine on a real driver-sqlite-wasm store, an object carrying a declared unique index on email. Two rows exist; the second is driven onto the first's value, so the UPDATE violates the index:

          {
          "threw": true,
          "name": "Error",
          "code": undefined,"status": undefined,"hasCause": false,
          "message": "update `duly_note` set `id` = 'JrzMrU3fJnc5__tV', `email` = 'a@b.example', `updated_at` = '2026-09-02T03:54:04.936Z' where `id` = 'JrzMrU3fJnc5__tV' -"
          }

          No code, no status, no cause — and the message is the compiled UPDATE statement with its bound values, exactly the shape #14095 measured on the insert side.

          Why it matters, and why it is not merely cosmetic

          The platform now has ONE contract for this condition on insert and none on update, which is worse than having neither: an application that correctly branches on code === 'DUPLICATE_RECORD' for its create path silently falls through to the generic error branch on its edit path, on every driver. "Renaming a record onto a name someone else already took" is the ordinary form-submission case, and it is the one that stays dialect-coupled.

          An application cannot close it locally for the same three reasons the insert card enumerated: branching on SQLITE_CONSTRAINT_UNIQUE couples it to one dialect, the message is a compiled statement, and isUniqueViolationError lives in @objectstack/types, which an application cannot resolve.

          The shape of the work

          The insert side landed as envelopeUniqueViolation(error, object) from packages/objectql/src/duplicate-record-error.ts, applied at each point a driver error leaves the insert door. The update door needs the same treatment at its own driver-error exits, with the same negative contract (only a recognised unique violation is enveloped; a NOT NULL, a deadlock, a missing table and an unreachable store leave untouched) and the same operator-log rule (the log takes cause, so the driver's diagnosis stays in the line).

          Two things the insert card settled that this one has to decide for itself:

          • update can refuse a MULTI-row write. Which row conflicted is a question the insert envelope never had to answer, and the driver's error may not answer it either. The envelope's field half is unaffected (uniqueViolationColumn reads the same channels), but a caller may reasonably want to know it was one of N.
          • upsert is the same door's neighbour and is deliberately excluded here: on some dialects an upsert converts a conflict into a merge, so "a unique violation escaped" means something different there. It deserves its own measurement before any envelope is put on it.

          Unassigned and untriaged.


          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 reference pattern this card is asked to mirror (envelopeUniqueViolation) is on main now, so the line was inert and misrepresented the card as gated. This card is already pm:dispatched, so nothing else changes.

          Generated by Claude Code

          Metadata

          Metadata

          Assignees

          Labels

          bugSomething isn't workingdomain:enginepriority: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

            engine.update still leaks the raw driver unique-violation error — the same defect one verb over from the insert door, with the whole UPDATE statement as its message #14390

            Description

            @os-musk

            Found while implementing #14095, whose scope was explicitly the INSERT door. Filed rather than widened into that PR.

            Measured

            Real ObjectQL engine on a real driver-sqlite-wasm store, an object carrying a declared unique index on email. Two rows exist; the second is driven onto the first's value, so the UPDATE violates the index:

            {
            "threw": true,
            "name": "Error",
            "code": undefined,"status": undefined,"hasCause": false,
            "message": "update `duly_note` set `id` = 'JrzMrU3fJnc5__tV', `email` = 'a@b.example', `updated_at` = '2026-09-02T03:54:04.936Z' where `id` = 'JrzMrU3fJnc5__tV' -"
            }

            No code, no status, no cause — and the message is the compiled UPDATE statement with its bound values, exactly the shape #14095 measured on the insert side.

            Why it matters, and why it is not merely cosmetic

            The platform now has ONE contract for this condition on insert and none on update, which is worse than having neither: an application that correctly branches on code === 'DUPLICATE_RECORD' for its create path silently falls through to the generic error branch on its edit path, on every driver. "Renaming a record onto a name someone else already took" is the ordinary form-submission case, and it is the one that stays dialect-coupled.

            An application cannot close it locally for the same three reasons the insert card enumerated: branching on SQLITE_CONSTRAINT_UNIQUE couples it to one dialect, the message is a compiled statement, and isUniqueViolationError lives in @objectstack/types, which an application cannot resolve.

            The shape of the work

            The insert side landed as envelopeUniqueViolation(error, object) from packages/objectql/src/duplicate-record-error.ts, applied at each point a driver error leaves the insert door. The update door needs the same treatment at its own driver-error exits, with the same negative contract (only a recognised unique violation is enveloped; a NOT NULL, a deadlock, a missing table and an unreachable store leave untouched) and the same operator-log rule (the log takes cause, so the driver's diagnosis stays in the line).

            Two things the insert card settled that this one has to decide for itself:

            • update can refuse a MULTI-row write. Which row conflicted is a question the insert envelope never had to answer, and the driver's error may not answer it either. The envelope's field half is unaffected (uniqueViolationColumn reads the same channels), but a caller may reasonably want to know it was one of N.
            • upsert is the same door's neighbour and is deliberately excluded here: on some dialects an upsert converts a conflict into a merge, so "a unique violation escaped" means something different there. It deserves its own measurement before any envelope is put on it.

            Unassigned and untriaged.


            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 reference pattern this card is asked to mirror (envelopeUniqueViolation) is on main now, so the line was inert and misrepresented the card as gated. This card is already pm:dispatched, so nothing else changes.

            Generated by Claude Code

            Metadata

            Metadata

            Assignees

            Labels

            bugSomething isn't workingdomain:enginepriority: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

              engine.update still leaks the raw driver unique-violation error — the same defect one verb over from the insert door, with the whole UPDATE statement as its message #14390

              Description

              @os-musk

              Found while implementing #14095, whose scope was explicitly the INSERT door. Filed rather than widened into that PR.

              Measured

              Real ObjectQL engine on a real driver-sqlite-wasm store, an object carrying a declared unique index on email. Two rows exist; the second is driven onto the first's value, so the UPDATE violates the index:

              {
              "threw": true,
              "name": "Error",
              "code": undefined,"status": undefined,"hasCause": false,
              "message": "update `duly_note` set `id` = 'JrzMrU3fJnc5__tV', `email` = 'a@b.example', `updated_at` = '2026-09-02T03:54:04.936Z' where `id` = 'JrzMrU3fJnc5__tV' -"
              }

              No code, no status, no cause — and the message is the compiled UPDATE statement with its bound values, exactly the shape #14095 measured on the insert side.

              Why it matters, and why it is not merely cosmetic

              The platform now has ONE contract for this condition on insert and none on update, which is worse than having neither: an application that correctly branches on code === 'DUPLICATE_RECORD' for its create path silently falls through to the generic error branch on its edit path, on every driver. "Renaming a record onto a name someone else already took" is the ordinary form-submission case, and it is the one that stays dialect-coupled.

              An application cannot close it locally for the same three reasons the insert card enumerated: branching on SQLITE_CONSTRAINT_UNIQUE couples it to one dialect, the message is a compiled statement, and isUniqueViolationError lives in @objectstack/types, which an application cannot resolve.

              The shape of the work

              The insert side landed as envelopeUniqueViolation(error, object) from packages/objectql/src/duplicate-record-error.ts, applied at each point a driver error leaves the insert door. The update door needs the same treatment at its own driver-error exits, with the same negative contract (only a recognised unique violation is enveloped; a NOT NULL, a deadlock, a missing table and an unreachable store leave untouched) and the same operator-log rule (the log takes cause, so the driver's diagnosis stays in the line).

              Two things the insert card settled that this one has to decide for itself:

              • update can refuse a MULTI-row write. Which row conflicted is a question the insert envelope never had to answer, and the driver's error may not answer it either. The envelope's field half is unaffected (uniqueViolationColumn reads the same channels), but a caller may reasonably want to know it was one of N.
              • upsert is the same door's neighbour and is deliberately excluded here: on some dialects an upsert converts a conflict into a merge, so "a unique violation escaped" means something different there. It deserves its own measurement before any envelope is put on it.

              Unassigned and untriaged.


              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 reference pattern this card is asked to mirror (envelopeUniqueViolation) is on main now, so the line was inert and misrepresented the card as gated. This card is already pm:dispatched, so nothing else changes.

              Generated by Claude Code

              Metadata

              Metadata

              Assignees

              Labels

              bugSomething isn't workingdomain:enginepriority: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

                engine.update still leaks the raw driver unique-violation error — the same defect one verb over from the insert door, with the whole UPDATE statement as its message #14390

                Description

                @os-musk

                Found while implementing #14095, whose scope was explicitly the INSERT door. Filed rather than widened into that PR.

                Measured

                Real ObjectQL engine on a real driver-sqlite-wasm store, an object carrying a declared unique index on email. Two rows exist; the second is driven onto the first's value, so the UPDATE violates the index:

                {
                "threw": true,
                "name": "Error",
                "code": undefined,"status": undefined,"hasCause": false,
                "message": "update `duly_note` set `id` = 'JrzMrU3fJnc5__tV', `email` = 'a@b.example', `updated_at` = '2026-09-02T03:54:04.936Z' where `id` = 'JrzMrU3fJnc5__tV' -"
                }

                No code, no status, no cause — and the message is the compiled UPDATE statement with its bound values, exactly the shape #14095 measured on the insert side.

                Why it matters, and why it is not merely cosmetic

                The platform now has ONE contract for this condition on insert and none on update, which is worse than having neither: an application that correctly branches on code === 'DUPLICATE_RECORD' for its create path silently falls through to the generic error branch on its edit path, on every driver. "Renaming a record onto a name someone else already took" is the ordinary form-submission case, and it is the one that stays dialect-coupled.

                An application cannot close it locally for the same three reasons the insert card enumerated: branching on SQLITE_CONSTRAINT_UNIQUE couples it to one dialect, the message is a compiled statement, and isUniqueViolationError lives in @objectstack/types, which an application cannot resolve.

                The shape of the work

                The insert side landed as envelopeUniqueViolation(error, object) from packages/objectql/src/duplicate-record-error.ts, applied at each point a driver error leaves the insert door. The update door needs the same treatment at its own driver-error exits, with the same negative contract (only a recognised unique violation is enveloped; a NOT NULL, a deadlock, a missing table and an unreachable store leave untouched) and the same operator-log rule (the log takes cause, so the driver's diagnosis stays in the line).

                Two things the insert card settled that this one has to decide for itself:

                • update can refuse a MULTI-row write. Which row conflicted is a question the insert envelope never had to answer, and the driver's error may not answer it either. The envelope's field half is unaffected (uniqueViolationColumn reads the same channels), but a caller may reasonably want to know it was one of N.
                • upsert is the same door's neighbour and is deliberately excluded here: on some dialects an upsert converts a conflict into a merge, so "a unique violation escaped" means something different there. It deserves its own measurement before any envelope is put on it.

                Unassigned and untriaged.


                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 reference pattern this card is asked to mirror (envelopeUniqueViolation) is on main now, so the line was inert and misrepresented the card as gated. This card is already pm:dispatched, so nothing else changes.

                Generated by Claude Code

                Metadata

                Metadata

                Assignees

                Labels

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

                Type

                Projects

                No projects

                  Milestone

                  No milestone

                  Relationships

                  None yet

                  Development

                  No branches or pull requests

                  Issue actions