Summary
prefer-get-error-message matches err instanceof Error ? err.message : String(err) and autofixes it to getErrorMessage(err) without checking that getErrorMessage is actually resolvable in the current file (imported, or locally defined) before firing.
Its sibling rule, prefer-get-error-message-over-string, already implements this check via hasResolvableLocalBinding(node, "getErrorMessage") and skips reporting when it fails. prefer-get-error-message has no equivalent guard, so the two rules are inconsistent: one is safe against "suggest calling an unimported helper," the other is not.
Where
eslint-factory/src/rules/prefer-get-error-message.ts — full rule body (~60 lines), no resolvability check anywhere before context.report/the fixer.
- Compare
eslint-factory/src/rules/prefer-get-error-message-over-string.ts — hasResolvableLocalBinding gate at the top of its CallExpression/template-literal handling (checks ImportBinding/FunctionName defs as always-available, else requires definitionNode.range[0] < node.range[0]).
Grounding
All 5 live call sites matching the exact err instanceof Error ? err.message : String(err) shape in actions/setup/js/**/*.cjs (non-test) currently already import getErrorMessage:
Live matching call sites (grep-verified)
complete_pre_created_check_run.cjs:57
upload_artifact.cjs:286
upload_artifact.cjs:301
upload_artifact.cjs:343
upload_artifact.cjs:391
All 5 files already require/import getErrorMessage, so today the missing check is latent, not exercised by a live false positive — but any new file that reaches for this exact ternary pattern before importing the helper will get an autofix suggestion that calls an undefined function, a regression this rule family already guards against elsewhere.
Ask
- Port
hasResolvableLocalBinding (or extract it to the shared rule-utils module and import it from both rules) into prefer-get-error-message.ts, gating the report/suggestion the same way prefer-get-error-message-over-string does.
- Add a test case: a file with the matching ternary but no
getErrorMessage import/definition should not report (or should report without offering the unsafe autofix suggestion — match whatever behavior the sibling rule uses for the equivalent case).
- Add a test case confirming the existing 5 live-shape files' pattern (ternary + prior import) still fires and autofixes correctly (no regression).
Acceptance criteria
Generated by 🤖 ESLint Refiner · agent · 280.9 AIC · ⌖ 9.73 AIC · ⊞ 5.3K · ◷
Summary
prefer-get-error-messagematcheserr instanceof Error ? err.message : String(err)and autofixes it togetErrorMessage(err)without checking thatgetErrorMessageis actually resolvable in the current file (imported, or locally defined) before firing.Its sibling rule,
prefer-get-error-message-over-string, already implements this check viahasResolvableLocalBinding(node, "getErrorMessage")and skips reporting when it fails.prefer-get-error-messagehas no equivalent guard, so the two rules are inconsistent: one is safe against "suggest calling an unimported helper," the other is not.Where
eslint-factory/src/rules/prefer-get-error-message.ts— full rule body (~60 lines), no resolvability check anywhere beforecontext.report/the fixer.eslint-factory/src/rules/prefer-get-error-message-over-string.ts—hasResolvableLocalBindinggate at the top of itsCallExpression/template-literal handling (checksImportBinding/FunctionNamedefs as always-available, else requiresdefinitionNode.range[0] < node.range[0]).Grounding
All 5 live call sites matching the exact
err instanceof Error ? err.message : String(err)shape inactions/setup/js/**/*.cjs(non-test) currently already importgetErrorMessage:Live matching call sites (grep-verified)
complete_pre_created_check_run.cjs:57upload_artifact.cjs:286upload_artifact.cjs:301upload_artifact.cjs:343upload_artifact.cjs:391All 5 files already
require/importgetErrorMessage, so today the missing check is latent, not exercised by a live false positive — but any new file that reaches for this exact ternary pattern before importing the helper will get an autofix suggestion that calls an undefined function, a regression this rule family already guards against elsewhere.Ask
hasResolvableLocalBinding(or extract it to the shared rule-utils module and import it from both rules) intoprefer-get-error-message.ts, gating the report/suggestion the same wayprefer-get-error-message-over-stringdoes.getErrorMessageimport/definition should not report (or should report without offering the unsafe autofix suggestion — match whatever behavior the sibling rule uses for the equivalent case).Acceptance criteria
prefer-get-error-messagedoes not offer/apply thegetErrorMessage(err)autofix suggestion whengetErrorMessageis not resolvable in scope.New unit tests cover both the negative (no binding) and positive (existing binding) cases.
Behavior matches (or explicitly documents any deliberate difference from)
prefer-get-error-message-over-string's existing resolvability gate.This issue will auto-expire if not addressed within 90 days.