FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

fix: stop CPU-limit aborts from poisoning Worker isolates by TheMeinerLP · Pull Request #348 · OneLiteFeatherNET/launchpad · GitHub

fix: stop CPU-limit aborts from poisoning Worker isolates - #348

Merged
TheMeinerLP merged 1 commit into
mainfrom
fix/i18n-redefine-500
Sep 23, 2026
Merged

TheMeinerLP merged 1 commit into
mainfrom
fix/i18n-redefine-500

Conversation

Copy link
Copy Markdown
Collaborator

Summary

Production answered 40–60 % of requests with 500 Cannot redefine property: $i18n, on every route and in both locales, even for strictly sequential requests. Cloudflare error 1102 appeared in between.

Cause (reproduced against the Workers preview of main):

  1. On Workers Free a request gets 10 ms CPU. A server render here needs more, so Cloudflare aborts renders midway with error 1102.
  2. The abort leaves Vue's module-global currentInstance pointing at the dead request.
  3. In the next request in that isolate, @nuxtjs/i18n resolves the Nuxt app via useNuxtApp(), which prefers getCurrentInstance()?.appContext.app.$nuxt. It gets the dead request's app, and Object.defineProperty(nuxt, "$i18n", …) throws.
  4. The isolate stays broken until Cloudflare recycles it.
Environment Load Result
wrangler dev locally (no CPU limit) 1,000 req, concurrency 100 0 errors
Workers preview of main (Free) 100 req, concurrency 5 34 ≥ 500: 4× 1102, 30× $i18n
Production (Free, old deploy) 15 sequential 10× 500
Production after upgrading to Workers Paid 100 req, concurrency 5 0 errors, no cross-request state

The Vue version is not the cause: 3.5.42 (production) and 3.5.43 (main) behave identically.

Changes

  • Account upgraded to Workers Paid, done in the dashboard. It removes the trigger by raising the CPU limit to a 30 s default.
  • limits.cpu_ms: 5000 in $production of nuxt.config.ts: a guard against runaway renders, far above a normal render. It will be re-tuned to 10× the measured p99 after 48 h. Free rejects limits, so this PR must only merge on Paid.
  • server/plugins/error-response-headers.ts: 5xx responses get X-Robots-Tag: noindex. Before, @nuxtjs/robots had already stamped index, follow before the render failed.
  • scripts/concurrency-check.mjs: load, locale-isolation and content-isolation checks. It runs in CI against pnpm preview:prod (new script, wrangler pinned as devDependency) and catches per-request state leaking into module scope. Run it against production after a deploy to catch CPU aborts, which wrangler dev cannot reproduce.
  • AGENTS.md: new "Deploy" section.

⚠️ Action required in the Cloudflare dashboard

Production does not run main. Every main check run of Workers Builds reports a Version ID and a Preview Alias URL (main-launchpad…workers.dev). The branch is treated as a preview branch: versions are uploaded, nothing is deployed. Production still serves Vue 3.5.42, while main has had 3.5.43 since #345 (2026-09-19).

Fix: Workers → launchpad → Settings → Builds. Set the production branch to main and the deploy command to npx wrangler deploy. Until then this PR, like every PR since #341, will not reach visitors.

Verification

  • pnpm test: 57 files, 186 tests green, including a new unit test for the robots plugin.
  • ESLint 317/319 errors, 36/36 warnings, TypeScript 21/21. No rise against the baseline.
  • .output/server/wrangler.json contains "limits": { "cpu_ms": 5000 }.
  • curl -I on a failing route under preview:prod shows x-robots-tag: noindex.
  • CI concurrency step green on this PR.
  • After the dashboard fix and the first deploy: the entry bundle on onelitefeather.net carries the lockfile's Vue version, and the concurrency check against production is green.
  • 48 h later: 5xx rate < 0.1 %, and no Exceeded CPU Time Limits / Exceeded Memory in the invocation statuses.

Follow-ups

  • Upstream issue for nuxt-modules/i18n: the plugin should use the app it is handed rather than useNuxtApp().
  • The planned edge-caching-and-seo change assumed the Free plan and gets revised for Paid.

🤖 Generated with Claude Code

https://claude.ai/code/session_012ZzvomAnwjAS3et96Avp7s

On the Workers Free plan a request gets 10 ms CPU. A server render here
needs more, so Cloudflare aborted renders midway (error 1102). The abort
left Vue's module-global current instance pointing at the dead request,
and every later request in that isolate failed in the @nuxtjs/i18n plugin
with "Cannot redefine property: $i18n" — 40-60 % of production requests.

The account now runs on Workers Paid, which removes the trigger. This
adds a generous `limits.cpu_ms` guard against runaway renders, marks 5xx
responses noindex (robots set "index, follow" before the render failed),
and adds a concurrency check that runs in CI against the production build
served by wrangler dev, and against production after a deploy.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012ZzvomAnwjAS3et96Avp7s

Copy link
Copy Markdown

Deploying with    Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
launchpad ff4c53e Commit Preview URL

Branch Preview URL
Sep 23 2026, 07:16 AM

TheMeinerLP merged commit b29f461 into main Sep 23, 2026
7 checks passed
TheMeinerLP deleted the fix/i18n-redefine-500 branch September 23, 2026 07:17
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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant


Back | FazBrowse Home | New Git URL