Skip to content

eslint-factory: core-method-resolve.ts CORE_ALIASES gap makes 8 sibling rules blind to DI-style core parameter names #49489

Description

@github-actions

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 ·

  • expires on Aug 7, 2026, 10:28 PM UTC-08:00

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions