Skip to content

eslint-factory: require-new-url-try-catch — false positives for provably non-throwing new URL(...) arguments #46151

Description

@github-actions

Rule

require-new-url-try-catch

Summary

isDynamicArg treats every non-Literal, non-empty-TemplateLiteral first argument as runtime-dynamic and therefore parse-risky. Two argument shapes that provably never throw are still flagged, producing false positives:

  1. Compile-time constant string concatenationnew URL("(example.com/redacted)" + "/path"). The argument is a BinaryExpression of two string literals; it evaluates to a constant valid URL and cannot throw.
  2. import.meta.url as the sole / first argumentnew URL(import.meta.url). import.meta.url is always a valid absolute URL in ES modules, so the constructor never throws. The rule already whitelists import.meta.url via isKnownSafeBase, but only for the second (base) argument; the same value in first-argument position is flagged.

Reproduction (currently flagged, should be valid)

// (1) constant concatenation — never throws
new URL("(example.com/redacted)" + "/repos");
// (2) import.meta.url as sole argument — never throws (ES module)
const u = new URL(import.meta.url);

Consistency rationale

The sibling rule no-github-request-interpolated-route explicitly accepts compile-time constant concatenations ("GET /repos" + "/{owner}/{repo}") as safe (see eslint-factory/README.md). require-new-url-try-catch should apply the same "provably-constant is safe" principle, and should honor its own isKnownSafeBase whitelist symmetrically in first-argument position.

Grounding / severity

Logic-derived precision refinement; low current frequency in actions/setup/js (the live new URL(...) sites use genuinely dynamic arguments — e.g. generate_history_link.cjs:61, awf_reflect.cjs:140 (already wrapped), sanitize_content_core.cjs:85 — and are handled correctly). Filed to prevent false positives that would push authors to wrap statements that cannot fail.

Acceptance criteria

  • Treat a BinaryExpression whose operands are (recursively) string literals / expression-less template literals as a non-dynamic, non-throwing argument.
  • Reuse isKnownSafeBase for the first argument as well, so new URL(import.meta.url) is not flagged.
  • Add valid-case tests for both forms above; keep existing invalid cases (new URL(host + "/x") where host is a variable must still flag) to confirm the fix only exempts provably-constant / known-safe values.
  • Leave genuinely dynamic single-variable and template-with-expression arguments in scope (no change).

Generated by 🤖 ESLint Refiner · 429.1 AIC · ⌖ 13.4 AIC · ⊞ 4.6K ·

  • expires on Jul 23, 2026, 10:20 PM UTC-08:00

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

cookieIssue Monster Loves Cookies!eslint

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions