github / github/gh-aw

[eslint-miner] eslint-factory: add require-fs-stat-access-try-catch rule

Open
#60,804 0 comments 0 reactions 0 assignees View on GitHub
agentic-workflows automation cookie eslint
Dominant language
Go
Stars
5.1k
Forks
541
Avg merge
5h 48m
Merged PRs (30d)
773

Description

> [!TIP]
> **Your pull request is ready to create! 🎉 ✅**
>
> Everything is OK—the changes have been pushed to a branch. Please review the protected files, then create the pull request when you are ready.
>
> **[Create the pull request](https://github.com/github/gh-aw/compare/main...eslint-miner/fs-stat-access-try-catch-35f6e519ab30a627?expand=1&title=%5Beslint-miner%5D%20eslint-factory%3A%20add%20require-fs-stat-access-try-catch%20rule&body=Closes%20%2360804)**
>
> The original pull request description is below.

---

### ESLint Miner: new rule `require-fs-stat-access-try-catch`

Adds one net-new custom ESLint rule enforcing try/catch wrapping for `fs.lstatSync`, `fs.accessSync`, and `fs.readlinkSync` calls in `actions/setup/js`.

**Why this gap existed:** existing fs-sync try/catch rules cover `readFileSync`/`writeFileSync`/`appendFileSync` (`require-fs-sync-try-catch`), `statSync`/`readdirSync`/`copyFileSync`/`unlinkSync`/`renameSync` (`require-fs-io-try-catch`), and `realpathSync` alone (`require-realpathsync-try-catch`) — but nothing covered `lstatSync`, `accessSync`, or `readlinkSync`, all of which throw synchronously on missing paths or permission errors and are used across symlink-guard and validation code paths.

**Evidence (static scan of `actions/setup/js`):** `gh` issue/discussion search was not available in this sandbox (CLI/API errors), so this rule was derived from a codebase scan for recurring unguarded fs sync calls.

Running `npm run lint:setup-js` flags 3 real unguarded call sites:
- `azure_devops_work_items.cjs:460` — `fs.lstatSync(current)` inside a loop, not directly wrapped at the call site.
- `memory_custom_validation.cjs:203` — `fs.readlinkSync(fullPath)` inside a recursive directory-walk helper.
- `symlink_guard.cjs:32` — `fs.lstatSync(filePath)` in the shared `lstatGuard()` helper (the file's own docstring already tells callers "Throws if `filePath` does not exist — callers that need to tolerate non-existent paths should wrap the call in a try/catch", so this is a useful reminder rather than a false positive).

Already-wrapped call sites (`mcp_server_core.cjs`, `mcp_cli_bridge.cjs`, `merge_remote_agent_github_folder.cjs`) are correctly left unflagged, indicating a low false-positive rate.

**Implementation:**
- `eslint-factory/src/rules/require-fs-stat-access-try-catch.ts` — new rule, modeled on `require-fs-io-try-catch.ts`, reusing shared helpers from `try-catch-rule-utils.ts` (`createFsSyncMethodResolver`, `isInsideTryBlock`, `findEnclosingStatement`, `buildTryCatchSuggestion`). Provides a `suggest` fix (not autofix) that wraps the offending statement in try/catch and re-throws with `{ cause }`.
- `eslint-factory/src/rules/require-fs-stat-access-try-catch.test.ts` — unit tests covering CJS/ESM, destructured/aliased bindings, and non-fs receivers.
- Registered in `eslint-factory/src/index.ts` and enabled as `"warn"` in `eslint-factory/eslint.config.cjs`.
- Documented in `eslint-factory/README.md`.

**Validation:**
- `npm install` ✅
- `npm run build` ✅
- `npx vitest run` — 684/684 tests pass (67 files), including the new rule's tests and the README/index parity check ✅
- `npm run lint:setup-js` ✅ (0 errors, 89 warnings total incl. 3 new from this rule)

**Scope:** changes limited to `eslint-factory/**` (TypeScript rule + tests + config + docs). No `actions/setup/js` source files were modified — the 3 flagged call sites are left for maintainers to address separately.

No steering issue number was provided for this run, so no `steer` feedback comments were available to incorporate.

---

> [!NOTE]
> **Protected files**
>
> This patch modifies protected files, which may affect project dependencies, CI/CD pipelines, or agent behaviour.
>
>
> 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.

> Generated by [ESLint Miner](https://github.com/github/gh-aw/actions/runs/34824807418) · copilot · auto · 272 AIC · ⌖ 23 AIC · ⊞ 7.2K · [◷](https://github.com/search?q=repo%3Agithub%2Fgh-aw+%22gh-aw-workflow-id%3A+eslint-miner%22&type=pullrequests)
> - [x] expires on Sep 21, 2026, 1:12 AM UTC-08:00

Contributor guide

Open the contributing guide

Research direction

Start with eslint-factory/src/rules/require-fs-io-try-catch.ts and the shared helpers in try-catch-rule-utils.ts, then review the named test, index, config, and README files. Run the rule tests and the listed build, full-test, and lint commands; done means the new rule is registered, documented, tested across the stated binding forms, and all validation passes.

Written by the indexing model from the issue text.

Assessment

Tech stack
eslint, typescript
Domain
documentation, testing, tooling
Issue type
Feature
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
20/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.