[eslint-miner] eslint-factory: add no-string-fallback-for-non-string-message rule - #55052
Draft
github-actions[bot] wants to merge 1 commit into
Draft
Conversation
Detects the pattern: typeof <chain>.message === "string" ? <chain>.message : String(<container>) where the String() fallback stringifies a different (container) expression than the .message chain under test. When .message exists but is non-string, this silently produces "[object Object]" instead of coercing the message value itself. This mirrors the real bug reported in issue #55014 (error_helpers.cjs getErrorMessage()) and the rule additionally flags 4 live occurrences of the same anti-pattern in actions/setup/js: dispatch_workflow.cjs, log_parser_shared.cjs, route_slash_command.cjs, and safeoutputs_cli.cjs. Registered at warn severity in eslint.config.cjs. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
New ESLint rule
no-string-fallback-for-non-string-messageforeslint-factory(targetsactions/setup/js/**/*.cjs).Motivation
Issue #55014 (MCE-006, Safe Outputs Conformance) found a real bug in
error_helpers.cjs'sgetErrorMessage():When a thrown value has a non-string
.messageproperty, this pattern falls back to stringifying the entire container object instead of coercing the message itself — producing"[object Object]"in user-facing error output (a violation of the safe-outputs spec, Section 8.2).Scanning
actions/setup/jsfor the same shape (typeof X.message === "string" ? X.message : String(<different-expr>)) turned up 4 more live occurrences of the identical anti-pattern:dispatch_workflow.cjs:304route_slash_command.cjs:374log_parser_shared.cjs:1009safeoutputs_cli.cjs:48This is a recurring, structural bug shape — not a one-off — so a rule is warranted to prevent regressions and catch new instances.
Rule design
no-string-fallback-for-non-string-messageflags aConditionalExpressionwhere:typeof <chain>.message === "string"(optionally guarded by a leading&&, e.g.typeof x === "object" && typeof x.message === "string").<chain>.message.String(<container>), where<container>is a different expression than<chain>.message.Low false-positive risk: it only fires when the fallback's
String()argument is structurally distinct from the tested.messagechain — legitimate cases where the fallback already coerces the same chain (String(err.message)) are accepted as valid.Registered at
warnseverity (consistent with most rules in this factory) since this needs a case-by-case fix decision at each call site (the correct fallback value differs contextually).Validation
lint:setup-jsoutput includes the 4 real flagged sites (evidence of value, 0 false positives observed across fullactions/setup/jsscan):New rule unit tests (
no-string-fallback-for-non-string-message.test.ts) pass, covering valid (correct-fallback / unrelated-conditional) and invalid (container-stringified) cases.Scope
eslint-factory/.