[eslint-refiner] ESLint Refiner daily report — 2026-09-16 #61286
Closed
Replies: 1 comment
|
This discussion has been marked as outdated by ESLint Refiner. A newer discussion is available at Discussion #61544. |
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
ESLint Refiner — daily report (2026-09-16)
Scope this run:
require-error-code-in-thrown-error(top carried-over priority from 2026-09-15, first-ever grounding of this rule), plus a lighter secondary pass onrequire-fetch-try-catch.Key metrics
eslint-factory(unchanged since 2026-09-10)require-error-code-in-thrown-errorgh api ...labels=eslint-factory); 2 more expired/closed silently since yesterday (#59378,#59377,require-fs-close-sync)Issues filed
messageReferencesErrorCoderesolves a top-levelIdentifiermessage (e.g.const msg = ERR_API + ...; throw new Error(msg)) viaresolveWriteOnceInitializerChain, but when that same alias appears nested inside a+concatenation or a template-literal interpolation (throw new Error(prefix + ": failed"),throw new Error(`${prefix}: failed`)), the rule only checks the identifier's bare name and misses the resolution — a falsemissingErrorCode. Latent (no live misfire found across 128 importing files today), but the idiom is ordinary and the blast radius is rule-mechanism-wide.ERROR_CODE_PATTERNdoesn't recognizeerror_codes.cjs's own non-ERR_*/E0xxexports — the module the rule cites as its source of truth also exportsCONFIG_HASH_MISMATCH,RATE_LIMIT_EXCEEDED, andPOLICY_FILE_PROTECTION_DENIED_REASON_CODE, none of which match the rule's recognition regex. Currently these are only used withcore.setFailed()/ returned objects, never as the sole code in a thrownError, so there's no live misfire — but the mismatch is demonstrable directly fromerror_codes.cjs's own export list.Full analysis and repro traces
require-error-code-in-thrown-error(eslint-factory/src/rules/require-error-code-in-thrown-error.ts) had never been grounded against the live corpus before — 128 ofactions/setup/js's files importerror_codes.cjs, too many to review file-by-file, so this run audited the rule's own helper functions for internal asymmetries first, then grepped the corpus for the specific shapes those asymmetries predict.Finding 1 trace: for
const prefix = ERR_API; throw new Error(prefix + ": failed");, the throw argument is a top-levelBinaryExpression.auditMessageExpressioncallsmessageReferencesErrorCode(node)first, which recurses intoleft(Identifier "prefix") andright(string literal), testing each by bare name —"prefix"fails theERROR_CODE_PATTERNregex, and the literal has noERR_text. Since the overall node type isBinaryExpression(notCallExpressionorIdentifier),auditMessageExpressionfalls through toreturn "missingCode"— even thoughprefixprovably resolves toERR_APIone hop away. The same root cause reproduces for a template-literal interpolation (`${prefix}: failed`) and for a helper function whose single return statement has this shape. A search acrossactions/setup/js/*.cjsfor= fetch(/throw new Error(<ident> +-style aliasing found zero live occurrences today — this is a latent gap, not a currently-misfiring diagnostic, but "assign a code to a local const before concatenating" is a completely ordinary refactor with nothing in the codebase discouraging it.Finding 2 trace:
error_codes.cjs:61-72,87-89exportsCONFIG_HASH_MISMATCH = "CONFIG_HASH_MISMATCH",RATE_LIMIT_EXCEEDED = "RATE_LIMIT_EXCEEDED", andPOLICY_FILE_PROTECTION_DENIED_REASON_CODE = "POLICY_FILE_PROTECTION_DENIED"alongside theERR_*/SAFE_OUTPUT_E0xxconstants. None of the three containERR_or a 3-digitEcode, soERROR_CODE_PATTERN.test(...)is false for all of them. Today they're only consumed viacore.setFailed(...)(check_workflow_timestamp_api.cjs:426,453) or embedded in returned/thrown-adjacent objects (push_to_pull_request_branch.cjs:529,1123,approve_workflow_run.cjs:372,error_recovery.cjs:262-263) — never as the sole code inside a thrownError, so there's no live false positive yet, but the rule's own stated scope ("ERR_* from error_codes.cjs") is narrower than what that module actually exports.require-fetch-try-catch(never previously reviewed) got a lighter secondary pass: two plausible gaps were investigated — (a)isInsideTryBlock's "inline callback directly awaited" exception only unwraps one level of indirection, soawait Promise.all(items.map(async item => { await fetch(item.url); }))inside an outer try would likely still be misflagged even though the rejection legitimately propagates to the outer catch; (b)getAwaitedFetchInfoonly recognizes a fetch call as the immediate argument ofAwaitExpression, soconst p = fetch(url); await p;escapes detection entirely. Neither pattern was found live inactions/setup/jstoday, so neither was filed — left as a note in repo-memory for a future joint pass across the fetch-family rules (require-fetch-try-catch,require-fetch-timeout,require-fetch-response-body-try-catch), which likely share the same traversal shape.Next actions
require-mkdirsync-try-catch,require-rmsync-try-catch,require-spawnsync-error-check,require-fs-io-try-catch,require-fetch-timeout,require-fetch-response-body-try-catch.Warning
Firewall blocked 1 domain
The following domain was blocked by the firewall during workflow execution:
api.anthropic.comTo allow these domains, add them to the
network.allowedlist in your workflow frontmatter:See Network Configuration for more information.
All reactions