Skip to content

eslint-factory: require-return-after-core-setfailed misses bare switch-case fall-through (FN) and flags trailing function declar [Content truncated due to length] #46992

Closed

Description

@github-actions

Rule

require-return-after-core-setfailed (eslint-factory/src/rules/require-return-after-core-setfailed.ts)

This rule exists to catch the "execution continues after failure is declared" pattern. Two precision gaps were found by static review. Neither has live sites in actions/setup/js today, so both are regression-guard hardening (cheap, self-contained).


1. False negative — bare switch case fall-through (HIGH confidence, HIGH impact)

When core.setFailed(...) is the last statement of an un-braced case consequent and control falls through to the next case, the following code runs in a failed state but is not flagged:

switch (x) {
  case 1:
    core.setFailed("bad");   // falls through — NOT flagged
  case 2:
    doMore();                // runs after failure declared
}

Root cause: the SwitchCase visitor (rule lines ~338-340) only calls checkStatementList, which reports solely on an in-list next sibling (next = stmts[i+1]). When setFailed is the last consequent statement, next is undefined, so nothing fires. The dedicated switch-fall-through logic already present in findContinuationOutsideBlock (rule lines ~129-140) is only reachable via checkNestedContinuation, which is never invoked for a setFailed sitting directly in a SwitchCase consequent — so that code path is effectively dead for the bare case.

Proof it's a gap, not a design choice — the sibling shapes ARE flagged:

  • case "a": core.setFailed("bad"); doMore(); break; → flagged (test line 121, in-list sibling)
  • case 1: if (bad) { core.setFailed("x"); } case 2: doMore(); → flagged (test line 155, BlockStatement visitor fires)

Only the bare, last-in-consequent shape slips through — an inconsistency.

Fix: in the SwitchCase visitor, also run checkNestedContinuation on the last consequent statement when it is a setFailed (reuses the existing findContinuationOutsideBlock machinery, which already handles switch fall-through).

2. False positive — trailing hoisted function declaration (HIGH confidence, LOW impact)

core.setFailed("bad");
function helper() {}   // hoisted, never "runs" — but currently flagged

Root cause: isExecutableStatement (rule lines ~57-65) excludes ImportDeclaration/ExportAllDeclaration/ExportDefaultDeclaration/ExportNamedDeclaration/TSModuleDeclaration but not FunctionDeclaration. So a hoisted function declaration becomes next, isControlTransfer returns false, and a spurious report fires. A hoisted declaration has no runtime continuation effect.

Fix: treat FunctionDeclaration (and likely TSInterfaceDeclaration/TSTypeAliasDeclaration) as non-continuation in isExecutableStatement.


Acceptance criteria

  • switch (x) { case 1: core.setFailed("bad"); case 2: doMore(); } is flagged with missingReturnAfterSetFailed (new invalid test).
  • Braced/in-sibling/if-wrapped switch cases (existing tests, lines 121 & 155) remain unchanged.
  • core.setFailed("bad"); function helper() {} at module top level is not flagged (new valid test).
  • A terminating case — case 1: core.setFailed("bad"); break; case 2: doMore(); — remains valid (regression test).
  • npm test passes.

Grounding

No live sites in actions/setup/js (verified: no switch+setFailed fall-through, no top-level function decl after setFailed). Both are regression-guard hardening. Found via static soundness review; consistency with the rule's already-handled if/braced variants makes #1 high-confidence.

Generated by 🤖 ESLint Refiner · 455.7 AIC · ⌖ 10.8 AIC · ⊞ 4.6K · ◷

  • expires on Jul 27, 2026, 10:19 PM UTC-08:00

Activity

  1. github-actions commented on Jul 21, 2026

    @github-actions
    ContributorAuthor

    🍪 Issue Monster selected this for Copilot

    I have identified this issue as a good candidate for automated resolution and requested assignment to the Copilot coding agent.

    If assignment succeeds, the Copilot coding agent will analyze the issue and create a pull request with the fix.

    Om nom nom! 🍪

    Warning

    Firewall blocked 1 domain

    The following domain was blocked by the firewall during workflow execution:

    • pi.dev

    To allow these domains, add them to the network.allowed list in your workflow frontmatter:

    network:
      allowed:
        - defaults
        - "pi.dev"

    See Network Configuration for more information.

    🍪 Om nom nom by Issue Monster · gpt54 2.78 AIC · ⌖ 5.08 AIC · ⊞ 6.3K · ◷

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

Metadata

Metadata

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions