Skip to content

eslint-factory: no-core-error-then-process-exit only checks adjacent statements — misses intervening statements (FN) #46993

Closed

Description

@github-actions

Rule

no-core-error-then-process-exit (eslint-factory/src/rules/no-core-error-then-process-exit.ts)

The rule flags core.error(msg); process.exit(nonzero) and steers toward core.setFailed(msg). It only inspects immediately adjacent statements (current = stmts[i], next = stmts[i+1] in checkStatements, rule lines ~139-143), so any statement between the core.error(...) and the process.exit(nonzero) defeats detection:

core.error("fatal: could not load config");
core.summary.addRaw("fatal");   // any intervening statement
process.exit(1);                 // NOT flagged today

The anti-pattern is unchanged by an intervening log/summary line — it is still core.error used to fail instead of core.setFailed, followed by a hard process.exit(nonzero).

Contrast with the sibling rule

require-return-after-core-setfailed performs cross-statement / nested continuation analysis. no-core-error-then-process-exit is adjacency-only, which is inconsistent and under-covers.

Existing tests

Only adjacent pairs are covered (core.error("..."); process.exit(1);). No test exercises an intervening statement.

Proposed refinement

Within the same statement list (block / switch-case / program body), after a core.error(...) statement, scan forward for a process.exit(nonzero) before any of:

  • a core.setFailed(...) call (that already fixes the failure signalling — do not flag), or
  • a control-transfer statement (return / throw / break / continue), or
  • a nested container that changes flow (be conservative — only scan the flat sibling list to avoid FPs).

Keep the existing autofix/suggestion behavior for the directly-adjacent case; the widened detection can report without a suggestion when the pair is non-adjacent (or extend the fixer to remove the process.exit and rewrite the core.error).

Acceptance criteria

  • core.error("x"); core.info("y"); process.exit(1); is flagged.
  • core.error("x"); core.setFailed("x"); process.exit(1); is not flagged (setFailed already present).
  • core.error("x"); process.exit(0); remains valid (clean exit).
  • All existing valid/invalid adjacency tests remain unchanged.
  • npm test passes.

Grounding

No live sites in actions/setup/js (no process.exit / core.error in non-test .cjs). This is regression-guard hardening. Confidence: medium; the scan-forward variant is a small, well-scoped change but must guard against FPs (hence the intervening-setFailed and control-transfer stops above).

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've 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 · 2.79 AIC · ⌖ 5.42 AIC · ⊞ 7K · ◷

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