validateExpression hands the dialect prescription to a stdlib function called as a receiver method (record.name.upper()) - advice that cannot succeed #14203

Description

@claude

Summary

A bare-callable stdlib function invoked as a receiver methodrecord.name.upper() — is
refused correctly and then handed the generic dialect prescription, which cannot succeed: the
source already is bare CEL and parses fine. Same defect family as the bounds class (#7073 /
PR #7209) and the unknown-name class (#13821); this is the arm neither of them covers.

Measured

packages/formula @ 4d672c4f, @marcbachmann/cel-js@8.0.0:

validateExpression('predicate', "record.name.upper()").errors[0].message
invalid CEL predicate: found no matching overload for 'dyn.upper()'
> 1 | record.name.upper()
^ — predicates are bare CEL (e.g. `record.rating >= 4`).

Why the #13821 repair deliberately does not cover it

#13821 gives the type class a prescription that names the unresolvable function and points at
the callable set, but it fires only when the name is absent from CEL_STDLIB_FUNCTIONS.
upper is present — it is a real, advertised function — so the new arm stays silent by design:
telling this author that upper "is not a callable name" would replace a useless sentence with a
false one. The name is right; the call shape is wrong.

Why it matters

This is a high-frequency AI-author mistake, not an exotic one: method-call syntax is what almost
every other language uses for string operations, so a generator that knows upper exists will
reach for record.name.upper() before upper(record.name). The membership rule of
CEL_STDLIB_FUNCTIONS is bare-callability (its doc-comment is explicit, and the drift pin
enforces it), so every one of the advertised names has a wrong receiver form an author can write.
The refusal is the publish-time guard #13594 documents, and the runtime consequence is
fail-closed and near-silent.

The remedy is one sentence and it is mechanical — the correct spelling is derivable from the
fault itself: upper(record.name).

Suggested direction (not a decision)

When the name extracted from cel-js's found no matching overload for 'RECEIVER.NAME(...)'
is in the advertised set, prescribe the bare call shape rather than the dialect. Note the
inverse case exists too and must not be broken: the 33 receiver-only names cel-js registers
(split, map, getFullYear) are correct only as receiver calls, so this arm must key on
membership of the bare-callable catalog, not on the call shape alone.

Out of scope for #13821, whose fence is the unknown-name class. Filed unassigned from that
card's dev seat. Searched the 444 open issues before filing — no duplicate.


Generated by Claude Code

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

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

    validateExpression hands the dialect prescription to a stdlib function called as a receiver method (record.name.upper()) - advice that cannot succeed #14203

    Description

    @claude

    Summary

    A bare-callable stdlib function invoked as a receiver methodrecord.name.upper() — is
    refused correctly and then handed the generic dialect prescription, which cannot succeed: the
    source already is bare CEL and parses fine. Same defect family as the bounds class (#7073 /
    PR #7209) and the unknown-name class (#13821); this is the arm neither of them covers.

    Measured

    packages/formula @ 4d672c4f, @marcbachmann/cel-js@8.0.0:

    validateExpression('predicate', "record.name.upper()").errors[0].message
    invalid CEL predicate: found no matching overload for 'dyn.upper()'
    > 1 | record.name.upper()
    ^ — predicates are bare CEL (e.g. `record.rating >= 4`).
    

    Why the #13821 repair deliberately does not cover it

    #13821 gives the type class a prescription that names the unresolvable function and points at
    the callable set, but it fires only when the name is absent from CEL_STDLIB_FUNCTIONS.
    upper is present — it is a real, advertised function — so the new arm stays silent by design:
    telling this author that upper "is not a callable name" would replace a useless sentence with a
    false one. The name is right; the call shape is wrong.

    Why it matters

    This is a high-frequency AI-author mistake, not an exotic one: method-call syntax is what almost
    every other language uses for string operations, so a generator that knows upper exists will
    reach for record.name.upper() before upper(record.name). The membership rule of
    CEL_STDLIB_FUNCTIONS is bare-callability (its doc-comment is explicit, and the drift pin
    enforces it), so every one of the advertised names has a wrong receiver form an author can write.
    The refusal is the publish-time guard #13594 documents, and the runtime consequence is
    fail-closed and near-silent.

    The remedy is one sentence and it is mechanical — the correct spelling is derivable from the
    fault itself: upper(record.name).

    Suggested direction (not a decision)

    When the name extracted from cel-js's found no matching overload for 'RECEIVER.NAME(...)'
    is in the advertised set, prescribe the bare call shape rather than the dialect. Note the
    inverse case exists too and must not be broken: the 33 receiver-only names cel-js registers
    (split, map, getFullYear) are correct only as receiver calls, so this arm must key on
    membership of the bare-callable catalog, not on the call shape alone.

    Out of scope for #13821, whose fence is the unknown-name class. Filed unassigned from that
    card's dev seat. Searched the 444 open issues before filing — no duplicate.


    Generated by Claude Code

    Activity

    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

    Metadata

    Metadata

    Assignees

    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

      validateExpression hands the dialect prescription to a stdlib function called as a receiver method (record.name.upper()) - advice that cannot succeed #14203

      Description

      @claude

      Summary

      A bare-callable stdlib function invoked as a receiver methodrecord.name.upper() — is
      refused correctly and then handed the generic dialect prescription, which cannot succeed: the
      source already is bare CEL and parses fine. Same defect family as the bounds class (#7073 /
      PR #7209) and the unknown-name class (#13821); this is the arm neither of them covers.

      Measured

      packages/formula @ 4d672c4f, @marcbachmann/cel-js@8.0.0:

      validateExpression('predicate', "record.name.upper()").errors[0].message
      invalid CEL predicate: found no matching overload for 'dyn.upper()'
      > 1 | record.name.upper()
      ^ — predicates are bare CEL (e.g. `record.rating >= 4`).
      

      Why the #13821 repair deliberately does not cover it

      #13821 gives the type class a prescription that names the unresolvable function and points at
      the callable set, but it fires only when the name is absent from CEL_STDLIB_FUNCTIONS.
      upper is present — it is a real, advertised function — so the new arm stays silent by design:
      telling this author that upper "is not a callable name" would replace a useless sentence with a
      false one. The name is right; the call shape is wrong.

      Why it matters

      This is a high-frequency AI-author mistake, not an exotic one: method-call syntax is what almost
      every other language uses for string operations, so a generator that knows upper exists will
      reach for record.name.upper() before upper(record.name). The membership rule of
      CEL_STDLIB_FUNCTIONS is bare-callability (its doc-comment is explicit, and the drift pin
      enforces it), so every one of the advertised names has a wrong receiver form an author can write.
      The refusal is the publish-time guard #13594 documents, and the runtime consequence is
      fail-closed and near-silent.

      The remedy is one sentence and it is mechanical — the correct spelling is derivable from the
      fault itself: upper(record.name).

      Suggested direction (not a decision)

      When the name extracted from cel-js's found no matching overload for 'RECEIVER.NAME(...)'
      is in the advertised set, prescribe the bare call shape rather than the dialect. Note the
      inverse case exists too and must not be broken: the 33 receiver-only names cel-js registers
      (split, map, getFullYear) are correct only as receiver calls, so this arm must key on
      membership of the bare-callable catalog, not on the call shape alone.

      Out of scope for #13821, whose fence is the unknown-name class. Filed unassigned from that
      card's dev seat. Searched the 444 open issues before filing — no duplicate.


      Generated by Claude Code

      Activity

      Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

      Metadata

      Metadata

      Assignees

      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

        validateExpression hands the dialect prescription to a stdlib function called as a receiver method (record.name.upper()) - advice that cannot succeed #14203

        Description

        @claude

        Summary

        A bare-callable stdlib function invoked as a receiver methodrecord.name.upper() — is
        refused correctly and then handed the generic dialect prescription, which cannot succeed: the
        source already is bare CEL and parses fine. Same defect family as the bounds class (#7073 /
        PR #7209) and the unknown-name class (#13821); this is the arm neither of them covers.

        Measured

        packages/formula @ 4d672c4f, @marcbachmann/cel-js@8.0.0:

        validateExpression('predicate', "record.name.upper()").errors[0].message
        invalid CEL predicate: found no matching overload for 'dyn.upper()'
        > 1 | record.name.upper()
        ^ — predicates are bare CEL (e.g. `record.rating >= 4`).
        

        Why the #13821 repair deliberately does not cover it

        #13821 gives the type class a prescription that names the unresolvable function and points at
        the callable set, but it fires only when the name is absent from CEL_STDLIB_FUNCTIONS.
        upper is present — it is a real, advertised function — so the new arm stays silent by design:
        telling this author that upper "is not a callable name" would replace a useless sentence with a
        false one. The name is right; the call shape is wrong.

        Why it matters

        This is a high-frequency AI-author mistake, not an exotic one: method-call syntax is what almost
        every other language uses for string operations, so a generator that knows upper exists will
        reach for record.name.upper() before upper(record.name). The membership rule of
        CEL_STDLIB_FUNCTIONS is bare-callability (its doc-comment is explicit, and the drift pin
        enforces it), so every one of the advertised names has a wrong receiver form an author can write.
        The refusal is the publish-time guard #13594 documents, and the runtime consequence is
        fail-closed and near-silent.

        The remedy is one sentence and it is mechanical — the correct spelling is derivable from the
        fault itself: upper(record.name).

        Suggested direction (not a decision)

        When the name extracted from cel-js's found no matching overload for 'RECEIVER.NAME(...)'
        is in the advertised set, prescribe the bare call shape rather than the dialect. Note the
        inverse case exists too and must not be broken: the 33 receiver-only names cel-js registers
        (split, map, getFullYear) are correct only as receiver calls, so this arm must key on
        membership of the bare-callable catalog, not on the call shape alone.

        Out of scope for #13821, whose fence is the unknown-name class. Filed unassigned from that
        card's dev seat. Searched the 444 open issues before filing — no duplicate.


        Generated by Claude Code

        Activity

        Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

        Metadata

        Metadata

        Assignees

        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

          validateExpression hands the dialect prescription to a stdlib function called as a receiver method (record.name.upper()) - advice that cannot succeed #14203

          Description

          @claude

          Summary

          A bare-callable stdlib function invoked as a receiver methodrecord.name.upper() — is
          refused correctly and then handed the generic dialect prescription, which cannot succeed: the
          source already is bare CEL and parses fine. Same defect family as the bounds class (#7073 /
          PR #7209) and the unknown-name class (#13821); this is the arm neither of them covers.

          Measured

          packages/formula @ 4d672c4f, @marcbachmann/cel-js@8.0.0:

          validateExpression('predicate', "record.name.upper()").errors[0].message
          invalid CEL predicate: found no matching overload for 'dyn.upper()'
          > 1 | record.name.upper()
          ^ — predicates are bare CEL (e.g. `record.rating >= 4`).
          

          Why the #13821 repair deliberately does not cover it

          #13821 gives the type class a prescription that names the unresolvable function and points at
          the callable set, but it fires only when the name is absent from CEL_STDLIB_FUNCTIONS.
          upper is present — it is a real, advertised function — so the new arm stays silent by design:
          telling this author that upper "is not a callable name" would replace a useless sentence with a
          false one. The name is right; the call shape is wrong.

          Why it matters

          This is a high-frequency AI-author mistake, not an exotic one: method-call syntax is what almost
          every other language uses for string operations, so a generator that knows upper exists will
          reach for record.name.upper() before upper(record.name). The membership rule of
          CEL_STDLIB_FUNCTIONS is bare-callability (its doc-comment is explicit, and the drift pin
          enforces it), so every one of the advertised names has a wrong receiver form an author can write.
          The refusal is the publish-time guard #13594 documents, and the runtime consequence is
          fail-closed and near-silent.

          The remedy is one sentence and it is mechanical — the correct spelling is derivable from the
          fault itself: upper(record.name).

          Suggested direction (not a decision)

          When the name extracted from cel-js's found no matching overload for 'RECEIVER.NAME(...)'
          is in the advertised set, prescribe the bare call shape rather than the dialect. Note the
          inverse case exists too and must not be broken: the 33 receiver-only names cel-js registers
          (split, map, getFullYear) are correct only as receiver calls, so this arm must key on
          membership of the bare-callable catalog, not on the call shape alone.

          Out of scope for #13821, whose fence is the unknown-name class. Filed unassigned from that
          card's dev seat. Searched the 444 open issues before filing — no duplicate.


          Generated by Claude Code

          Activity

          Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

          Metadata

          Metadata

          Assignees

          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

            validateExpression hands the dialect prescription to a stdlib function called as a receiver method (record.name.upper()) - advice that cannot succeed #14203

            Description

            @claude

            Summary

            A bare-callable stdlib function invoked as a receiver methodrecord.name.upper() — is
            refused correctly and then handed the generic dialect prescription, which cannot succeed: the
            source already is bare CEL and parses fine. Same defect family as the bounds class (#7073 /
            PR #7209) and the unknown-name class (#13821); this is the arm neither of them covers.

            Measured

            packages/formula @ 4d672c4f, @marcbachmann/cel-js@8.0.0:

            validateExpression('predicate', "record.name.upper()").errors[0].message
            invalid CEL predicate: found no matching overload for 'dyn.upper()'
            > 1 | record.name.upper()
            ^ — predicates are bare CEL (e.g. `record.rating >= 4`).
            

            Why the #13821 repair deliberately does not cover it

            #13821 gives the type class a prescription that names the unresolvable function and points at
            the callable set, but it fires only when the name is absent from CEL_STDLIB_FUNCTIONS.
            upper is present — it is a real, advertised function — so the new arm stays silent by design:
            telling this author that upper "is not a callable name" would replace a useless sentence with a
            false one. The name is right; the call shape is wrong.

            Why it matters

            This is a high-frequency AI-author mistake, not an exotic one: method-call syntax is what almost
            every other language uses for string operations, so a generator that knows upper exists will
            reach for record.name.upper() before upper(record.name). The membership rule of
            CEL_STDLIB_FUNCTIONS is bare-callability (its doc-comment is explicit, and the drift pin
            enforces it), so every one of the advertised names has a wrong receiver form an author can write.
            The refusal is the publish-time guard #13594 documents, and the runtime consequence is
            fail-closed and near-silent.

            The remedy is one sentence and it is mechanical — the correct spelling is derivable from the
            fault itself: upper(record.name).

            Suggested direction (not a decision)

            When the name extracted from cel-js's found no matching overload for 'RECEIVER.NAME(...)'
            is in the advertised set, prescribe the bare call shape rather than the dialect. Note the
            inverse case exists too and must not be broken: the 33 receiver-only names cel-js registers
            (split, map, getFullYear) are correct only as receiver calls, so this arm must key on
            membership of the bare-callable catalog, not on the call shape alone.

            Out of scope for #13821, whose fence is the unknown-name class. Filed unassigned from that
            card's dev seat. Searched the 444 open issues before filing — no duplicate.


            Generated by Claude Code

            Activity

            Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

            Metadata

            Metadata

            Assignees

            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

              validateExpression hands the dialect prescription to a stdlib function called as a receiver method (record.name.upper()) - advice that cannot succeed #14203

              Description

              @claude

              Summary

              A bare-callable stdlib function invoked as a receiver methodrecord.name.upper() — is
              refused correctly and then handed the generic dialect prescription, which cannot succeed: the
              source already is bare CEL and parses fine. Same defect family as the bounds class (#7073 /
              PR #7209) and the unknown-name class (#13821); this is the arm neither of them covers.

              Measured

              packages/formula @ 4d672c4f, @marcbachmann/cel-js@8.0.0:

              validateExpression('predicate', "record.name.upper()").errors[0].message
              invalid CEL predicate: found no matching overload for 'dyn.upper()'
              > 1 | record.name.upper()
              ^ — predicates are bare CEL (e.g. `record.rating >= 4`).
              

              Why the #13821 repair deliberately does not cover it

              #13821 gives the type class a prescription that names the unresolvable function and points at
              the callable set, but it fires only when the name is absent from CEL_STDLIB_FUNCTIONS.
              upper is present — it is a real, advertised function — so the new arm stays silent by design:
              telling this author that upper "is not a callable name" would replace a useless sentence with a
              false one. The name is right; the call shape is wrong.

              Why it matters

              This is a high-frequency AI-author mistake, not an exotic one: method-call syntax is what almost
              every other language uses for string operations, so a generator that knows upper exists will
              reach for record.name.upper() before upper(record.name). The membership rule of
              CEL_STDLIB_FUNCTIONS is bare-callability (its doc-comment is explicit, and the drift pin
              enforces it), so every one of the advertised names has a wrong receiver form an author can write.
              The refusal is the publish-time guard #13594 documents, and the runtime consequence is
              fail-closed and near-silent.

              The remedy is one sentence and it is mechanical — the correct spelling is derivable from the
              fault itself: upper(record.name).

              Suggested direction (not a decision)

              When the name extracted from cel-js's found no matching overload for 'RECEIVER.NAME(...)'
              is in the advertised set, prescribe the bare call shape rather than the dialect. Note the
              inverse case exists too and must not be broken: the 33 receiver-only names cel-js registers
              (split, map, getFullYear) are correct only as receiver calls, so this arm must key on
              membership of the bare-callable catalog, not on the call shape alone.

              Out of scope for #13821, whose fence is the unknown-name class. Filed unassigned from that
              card's dev seat. Searched the 444 open issues before filing — no duplicate.


              Generated by Claude Code

              Activity

              Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

              Metadata

              Metadata

              Assignees

              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

                validateExpression hands the dialect prescription to a stdlib function called as a receiver method (record.name.upper()) - advice that cannot succeed #14203

                Description

                @claude

                Summary

                A bare-callable stdlib function invoked as a receiver methodrecord.name.upper() — is
                refused correctly and then handed the generic dialect prescription, which cannot succeed: the
                source already is bare CEL and parses fine. Same defect family as the bounds class (#7073 /
                PR #7209) and the unknown-name class (#13821); this is the arm neither of them covers.

                Measured

                packages/formula @ 4d672c4f, @marcbachmann/cel-js@8.0.0:

                validateExpression('predicate', "record.name.upper()").errors[0].message
                invalid CEL predicate: found no matching overload for 'dyn.upper()'
                > 1 | record.name.upper()
                ^ — predicates are bare CEL (e.g. `record.rating >= 4`).
                

                Why the #13821 repair deliberately does not cover it

                #13821 gives the type class a prescription that names the unresolvable function and points at
                the callable set, but it fires only when the name is absent from CEL_STDLIB_FUNCTIONS.
                upper is present — it is a real, advertised function — so the new arm stays silent by design:
                telling this author that upper "is not a callable name" would replace a useless sentence with a
                false one. The name is right; the call shape is wrong.

                Why it matters

                This is a high-frequency AI-author mistake, not an exotic one: method-call syntax is what almost
                every other language uses for string operations, so a generator that knows upper exists will
                reach for record.name.upper() before upper(record.name). The membership rule of
                CEL_STDLIB_FUNCTIONS is bare-callability (its doc-comment is explicit, and the drift pin
                enforces it), so every one of the advertised names has a wrong receiver form an author can write.
                The refusal is the publish-time guard #13594 documents, and the runtime consequence is
                fail-closed and near-silent.

                The remedy is one sentence and it is mechanical — the correct spelling is derivable from the
                fault itself: upper(record.name).

                Suggested direction (not a decision)

                When the name extracted from cel-js's found no matching overload for 'RECEIVER.NAME(...)'
                is in the advertised set, prescribe the bare call shape rather than the dialect. Note the
                inverse case exists too and must not be broken: the 33 receiver-only names cel-js registers
                (split, map, getFullYear) are correct only as receiver calls, so this arm must key on
                membership of the bare-callable catalog, not on the call shape alone.

                Out of scope for #13821, whose fence is the unknown-name class. Filed unassigned from that
                card's dev seat. Searched the 444 open issues before filing — no duplicate.


                Generated by Claude Code

                Activity

                Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

                Metadata

                Metadata

                Assignees

                Type

                Projects

                No projects

                  Milestone

                  No milestone

                  Relationships

                  None yet

                  Development

                  No branches or pull requests

                  Issue actions