Skip to content

[eslint-miner] eslint-factory: add require-realpathsync-try-catch rule #56609

Description

@github-actions

Summary

Adds a new custom ESLint rule, require-realpathsync-try-catch, that requires fs.realpathSync() calls in actions/setup/js to be wrapped in try/catch.

Why

fs.realpathSync() throws synchronously when the target path is missing, permissions are denied, or a symlink cycle is encountered. In actions/setup/js these calls almost always feed a path-traversal / symlink-escape containment check (assertPathWithin(...)). An unhandled throw doesn't just crash with a generic stack trace — it means the containment check for that path is skipped entirely, and the original failure loses call-site-specific error context that a wrapped rethrow ({ cause }) would otherwise preserve.

This gap was reported in #56340 but never implemented — no existing rule in eslint-factory/src/rules references realpathSync (confirmed via grep across all ~70 existing rules before starting this work, to avoid duplicating coverage like require-fs-io-try-catch, which covers statSync/readdirSync/copyFileSync/unlinkSync/renameSync but not realpathSync).

Evidence

Running the new rule against actions/setup/js flags real, currently-unguarded call sites:

  • create_prompt.cjs:50fs.realpathSync(promptsDir)
  • create_prompt.cjs:56fs.realpathSync(unresolved)
  • create_files.cjs:104fs.realpathSync(root)
  • create_files.cjs:112fs.realpathSync(directoryPath)
  • create_files.cjs:128fs.realpathSync(parentPath)

All are outside any enclosing try block, so the rule correctly flags them while leaving calls already inside main()'s outer try/catch alone.

Implementation

Follows the exact pattern of require-mkdtempsync-try-catch:

  • FS_SYNC_METHODS = new Set(["realpathSync"])
  • Detection via createFsSyncMethodResolver (handles fs.realpathSync(...), fs["realpathSync"](...), destructured const { realpathSync } = require("fs"), and ESM namespace/named imports)
  • Skips calls already inside a try block (isInsideTryBlock)
  • Offers an autofix suggestion wrapping the call in try { ... } catch (err) { throw new Error("fs.realpathSync failed: " + ..., { cause: err }); }

Files changed

  • eslint-factory/src/rules/require-realpathsync-try-catch.ts — new rule
  • eslint-factory/src/rules/require-realpathsync-try-catch.test.ts — 11 test cases (valid/invalid, CJS/ESM, destructured imports, autofix output, non-fs receivers, async context)
  • eslint-factory/src/index.ts — registered the rule
  • eslint-factory/eslint.config.cjs — enabled as "warn"
  • eslint-factory/README.md — rule documentation (satisfies the index-readme-parity test)

Validation performed

  • cd eslint-factory && npm install — ok
  • npm run build — clean TypeScript compilation
  • npx vitest run671/671 tests pass across 64 files, including the new rule's 11 tests and the existing index-readme-parity test
  • npm run lint:setup-js — new rule fires on exactly the 5 real unguarded call sites listed above, with no unexpected new warnings elsewhere

Scope

Only touches eslint-factory/** (TypeScript rule + config + docs). No changes to actions/setup/js source or Go code, per the ESLint Miner's out-of-scope constraints — fixing the flagged call sites themselves is left to a follow-up change.

Steering

No steering-issue number was provided in this run's context (placeholder # in the workflow instructions), so no steer-tagged feedback could be retrieved or incorporated.


Warning

Protected Files

This was originally intended as a pull request, but the patch modifies protected files. These files may affect project dependencies, CI/CD pipelines, or agent behaviour. Please review the changes carefully before creating the pull request.

Click here to create the pull request once you have reviewed the changes

Protected files
  • README.md

To route changes like this to a review issue instead of blocking, configure protected-files: fallback-to-issue in your workflow configuration.

Warning

Firewall blocked 1 domain

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

  • github.com

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

network:
  allowed:
    - defaults
    - "github.com"

See Network Configuration for more information.

Generated by ESLint Miner · copilot · auto · 268.7 AIC · ⌖ 14.5 AIC · ⊞ 7K ·

  • expires on Sep 4, 2026, 4:44 AM UTC-08:00

Activity

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