Rules affected (shared utility)
eslint-factory/src/rules/core-method-resolve.ts (isCoreAliasIdentifier / isDestructuredCoreMethodIdentifier) is imported by 8 rules: require-return-after-core-setfailed, no-setfailed-then-exit-zero, no-core-error-then-process-exit, no-core-error-then-process-exitcode, no-core-error-then-setfailed, no-core-exportvariable-non-string, no-core-setoutput-non-string. All of them resolve a @actions/core-like receiver only via CORE_ALIASES = new Set(["core", "coreObj"]) (eslint-factory/src/rules/core-aliases.ts:4). A plain function parameter is recognized as core-like only when its literal name is core or coreObj (core-method-resolve.ts:33).
Problem
Any function using a differently-named dependency-injection parameter for @actions/core (a legitimate, idiomatic pattern — see JSDoc comment at the call site below) is completely invisible to all 8 rules above. There is no detection at all for misuse of core-like objects through such a parameter, regardless of which of the 8 anti-patterns is present.
Grounded evidence
actions/setup/js/validate_context_variables.cjs:142-182:
/**
* `@param` {typeof import('`@actions/core`')} coreArg - GitHub Actions core library
* `@param` {any} ctx - GitHub Actions context object
*/
async function validateContextVariables(coreArg, ctx) {
...
coreArg.setFailed(errorMessage);
throw new Error(errorMessage); // <-- currently safe only because a throw happens to follow
}
...
}
This is exactly the shape require-return-after-core-setfailed exists to check (control flow after setFailed), but because the parameter is named coreArg (not core/coreObj), the rule never inspects this function at all. If a future edit removed the throw (or introduced a conditional bypass), none of the 8 rules sharing this resolver would catch it. This is the only DI-named core parameter found in the corpus today, but it demonstrates a live, systemic blind spot in shared infrastructure that all 8 rules depend on.
Ask
Broaden isCoreAliasIdentifier (and isDestructuredCoreMethodIdentifier) to recognize additional DI parameter naming conventions beyond the fixed CORE_ALIASES set — for example, JSDoc @param {typeof import('@actions/core')} type annotations on the parameter (a strong, unambiguous signal already present in the corpus), while keeping the existing conservative exact-name matching as a fast path. Avoid broad prefix/regex matching per the existing code comment's stated rationale (would flag unrelated objects).
Acceptance criteria
- New valid/invalid test cases for at least
require-return-after-core-setfailed and no-core-setoutput-non-string covering a JSDoc-annotated non-canonical parameter name (e.g. coreArg, coreLib).
- Re-verify
validate_context_variables.cjs:181 is now recognized as a core-method call site (rule should confirm the existing throw makes it compliant, not report a false positive).
- Existing canonical
core/coreObj tests across all 8 rules remain passing (no regression).
- Do not widen matching to arbitrary parameter names without a JSDoc/type signal — keep the existing false-positive-avoidance rationale intact.
Generated by 🤖 ESLint Refiner · agent · 669.3 AIC · ⌖ 7.12 AIC · ⊞ 4.9K · ◷
Rules affected (shared utility)
eslint-factory/src/rules/core-method-resolve.ts(isCoreAliasIdentifier/isDestructuredCoreMethodIdentifier) is imported by 8 rules:require-return-after-core-setfailed,no-setfailed-then-exit-zero,no-core-error-then-process-exit,no-core-error-then-process-exitcode,no-core-error-then-setfailed,no-core-exportvariable-non-string,no-core-setoutput-non-string. All of them resolve a@actions/core-like receiver only viaCORE_ALIASES = new Set(["core", "coreObj"])(eslint-factory/src/rules/core-aliases.ts:4). A plain function parameter is recognized as core-like only when its literal name iscoreorcoreObj(core-method-resolve.ts:33).Problem
Any function using a differently-named dependency-injection parameter for
@actions/core(a legitimate, idiomatic pattern — see JSDoc comment at the call site below) is completely invisible to all 8 rules above. There is no detection at all for misuse ofcore-like objects through such a parameter, regardless of which of the 8 anti-patterns is present.Grounded evidence
actions/setup/js/validate_context_variables.cjs:142-182:This is exactly the shape
require-return-after-core-setfailedexists to check (control flow aftersetFailed), but because the parameter is namedcoreArg(notcore/coreObj), the rule never inspects this function at all. If a future edit removed thethrow(or introduced a conditional bypass), none of the 8 rules sharing this resolver would catch it. This is the only DI-named core parameter found in the corpus today, but it demonstrates a live, systemic blind spot in shared infrastructure that all 8 rules depend on.Ask
Broaden
isCoreAliasIdentifier(andisDestructuredCoreMethodIdentifier) to recognize additional DI parameter naming conventions beyond the fixedCORE_ALIASESset — for example, JSDoc@param {typeof import('@actions/core')}type annotations on the parameter (a strong, unambiguous signal already present in the corpus), while keeping the existing conservative exact-name matching as a fast path. Avoid broad prefix/regex matching per the existing code comment's stated rationale (would flag unrelated objects).Acceptance criteria
require-return-after-core-setfailedandno-core-setoutput-non-stringcovering a JSDoc-annotated non-canonical parameter name (e.g.coreArg,coreLib).validate_context_variables.cjs:181is now recognized as a core-method call site (rule should confirm the existingthrowmakes it compliant, not report a false positive).core/coreObjtests across all 8 rules remain passing (no regression).