Skip to content

[bug] @astrojs/cloudflare: \\breturn\\b regex incorrectly replaces .return() method calls in frontmatter dep scan #16551

@hunnyboy1217

Description

@hunnyboy1217

Astro Info

# Run `astro info` and paste output here

If this issue only occurs in one browser, which browser is a problem?

N/A — this is a build-time issue.

Describe the Bug

@astrojs/cloudflare's esbuild dep-scan plugin transforms .astro frontmatter by replacing return with throw to avoid esbuild's "Top-level return" error. The regex /\breturn\b/g is too broad: the word-boundary \b matches at . (a non-word character), so .return property accesses and method calls are also rewritten, producing invalid JavaScript and causing Vite's dependency optimization scan to fail.

Affected file: packages/integrations/cloudflare/src/esbuild-plugin-astro-frontmatter.ts lines 34–35

const contents = frontmatterMatch[1]
  .replace(/\breturn\s*;/g, 'throw 0;')
  .replace(/\breturn\b/g, 'throw ');   // ← over-matches .return

Examples of over-replacement in frontmatter:

Input After transform Effect
gen.return(value) gen.throw (value) Syntax error — obj.throw is illegal JS
iterator.return() iterator.throw () Dep scan fails
"return value" "throw value" String content silently corrupted

The same regex exists in packages/astro/src/vite-plugin-astro/compile.ts lines 114–115, but there it only fires inside an error-recovery path, so the impact is much lower.

The code already carries a // Known Limitation comment, but it misidentifies the problematic case — $return is actually safe (since $ is a word character and \b won't match). The real culprit, .return property access, is not called out.

What's the expected result?

Only bare top-level return statements should be replaced. The following patterns should pass through unchanged:

  • Property accesses: gen.return(), iterator.return(value)
  • String/template literals containing the word return
  • Named imports such as import { return as ret } from '...'

A minimal fix is using a negative lookbehind to exclude .return:

.replace(/(?<!\.)return\s*;/g, 'throw 0;')
.replace(/(?<!\.)return\b/g, 'throw ');

A fully correct fix would use an AST-based transform that skips member expressions, string literals, and template expressions entirely.

Link to Minimal Reproducible Example

https://github.com/Hunnyboy1217/return-regex-repro.git

Participation

  • I am willing to submit a pull request for this issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    - P3: minor bugAn edge case that only affects very specific usage (priority)pkg: astroRelated to the core `astro` package (scope)pkg: cloudflareRelated to the Cloudflare adapter

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions