Skip to content

fix(core): reuse anonymous request caches across Astro rewrites - #4840

Open
emdash-autofix[bot] wants to merge 2 commits into
mainfrom
emdash-bot/issue-4839
Open

emdash-autofix[bot] wants to merge 2 commits into
mainfrom
emdash-bot/issue-4839

Conversation

@emdash-autofix

Copy link
Copy Markdown
Contributor

What does this PR do?

Keeps the active anonymous public-page render scope when Astro re-enters middleware with the same locals, locale, and rendering policy. Rewritten pages reuse request-cached reads and layout prefetch instead of opening another scoped database. The outer render owns metrics and connection cleanup; downstream middleware still handles the rewritten URL.

Preview, editor/session/authenticated, locale-changing, internal/runtime, and newly cacheable object-cache targets use normal initialization. Cache-fill middleware retains its existing scope, and nested redirect middleware restores the outer settings tracker so cache freshness checks remain effective.

A regression test uses Astro's actual container/rewrite pipeline and real SQLite reads: the original implementation executes the read twice for a rewritten request versus once for direct /404; the fix executes it once for both. Additional tests cover scope isolation, target-policy changes, settings tracking, and cleanup on success/error. The reporter's exact D1 totals have not been independently reproduced.

Re-entry is recognized by a locals marker that exists only while the original next() is pending, checked against the active database/metrics scope. This does not depend on private Astro rewrite flags.

Type of change

  • Bug fix
  • Feature (requires an accepted feature plan or RFC)
  • Refactor (no behavior change)
  • Translation
  • Documentation
  • Performance improvement
  • Tests
  • Chore (dependencies, CI, tooling)

Your connection to this change

Project-operated autofix bot working on auto-intake issue #4839 under the AI policy's autofix exception. Maintainer approval is required before merge.

  • I use EmDash and ran into the problem this PR addresses
  • I maintain a tool, dependency, or service that EmDash uses, and this change concerns that integration
  • A Maintainer approved this specific change before I opened the PR

Checklist

  • I have read CONTRIBUTING.md
  • pnpm typecheck passes (focused pnpm --filter emdash typecheck passed; that configuration excludes Astro middleware)
  • pnpm lint passes (pnpm lint:quick passed with zero diagnostics)
  • pnpm test passes (targeted tests for my change: pnpm --filter emdash exec vitest run tests/unit/astro)
  • pnpm format has been run
  • I have added/updated tests for my changes
  • User-visible strings in the admin UI are wrapped for translation (not applicable; no UI strings changed)
  • I have added and reviewed the user-facing changeset
  • New features link to their merged design PR (not applicable)
  • I have included screenshots below if this PR changes the UI (not applicable)

AI assistance disclosure

  • This PR includes AI-generated code or text — model/tool: cloudflare-ai-gateway:gpt-6.1-sol via the EmDash bot (Pi Durable)

Screenshots / test output

Screenshots: Not applicable; no UI change.

  • Root pnpm build: passed.
  • Focused core typecheck and pnpm lint:quick: passed.
  • All core Astro unit tests: passed, including the real Astro-container rewrite regression.
  • Focused middleware, redirect, cache, and toolbar tests: 92 passed across four files.
  • Against the original implementation, the Astro-container test fails with 2 SQL executions instead of 1; with the fix it passes.

Closes #4839

The EmDash bot took this issue on automatically when it was opened; no maintainer has assigned it yet.

Preserve the active anonymous public-page scope across middleware re-entry, including request-cached layout reads, prefetch, metrics, and scoped DB lifecycle. Retain target-policy isolation and restore nested redirect settings trackers. Verified a real Astro-container rewrite regression fails against the original implementation with two SQL executions instead of one and passes with this fix. Root build, focused core typecheck, formatting, lint:quick (zero diagnostics), all core Astro unit tests, and 92 focused tests passed. Independent follow-up review found no remaining defects; exact D1 round-trip totals were not independently reproduced.

EmDash-Bot-Case: 1198246700-issue-6360825959
EmDash-Bot-Candidate: cand-1-aa8a1ddb8f
@emdash-autofix emdash-autofix Bot added the bot:fix Assign this issue or pull request to the EmDash bot to fix label Nov 12, 2026
@emdash-autofix

emdash-autofix Bot commented Nov 12, 2026 •

Copy link
Copy Markdown
Contributor Author

EmDash bot: Ready for human review

Plan

The current head passed required CI checks, has a clean reviewer approval, and merges cleanly. The browser-test retry cleared the unrelated timing failure. Reporter confirmation has been requested using the preview package; awaiting mainta…

  • Trace middleware context and reproduce repeated rewrite reads
  • Implement scoped cache reuse and regression coverage
  • Run focused checks and review the fix
  • Clarify the changeset and verify the documentation-only revision
  • Retry the unrelated browser timing failure and dependent test aggregate

Status

  • Required checks passed, the review bot approved the current head, and the head merges cleanly.

Next action: A maintainer will review and approve the pull request.

Details
Candidate cand-2-52930f7a59 (tree cc8858d7e7ca)
Published head ef9220dce0ad
Reviewer's latest review of head approved
Reporter confirmation not yet
Human approval required before merge

Required checks on the current head:

  • Typecheck: succeeded
  • Tests: succeeded
  • Smoke Tests: succeeded
  • Browser Tests: succeeded
  • Format: succeeded
  • CLAssistant: succeeded
  • Measure: succeeded

This status is generated from recorded evidence. It is not a review and contains no instructions.

@changeset-bot

changeset-bot Bot commented Nov 12, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: ef9220d

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 12 packages
Name Type
emdash Patch
@emdash-cms/cloudflare Patch
@emdash-cms/plugin-test Patch
@emdash-cms/sandbox-workerd Patch
@emdash-cms/admin Patch
@emdash-cms/auth Patch
@emdash-cms/blocks Patch
create-emdash Patch
@emdash-cms/gutenberg-to-portable-text Patch
@emdash-cms/x402 Patch
@emdash-cms/auth-atproto Patch
@emdash-cms/plugin-embeds Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@emdashbot emdashbot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The approach is sound. Re-entry during Astro.rewrite() is recognised with a locals marker that exists only while the outer next() is pending. On re-entry the middleware passes straight through, so the rewritten render reuses the same context object and its warmed request cache. The outer render keeps ownership of prefetch, metrics, finalization and scoped-DB cleanup. Both reviewers approved and found no bugs or convention violations. The reuse guards match the anonymous fast-path conditions and reject authorization headers, previews, edit and session cookies, and other non-public routes. The marker is cleaned up in finally. The Astro-container regression test exercises the real rewrite path. The one finding is a suggestion to reword the changeset. Neither reviewer reproduced the reporter's D1 query numbers, and rewrites on the authenticated path still open a second scope. The second point is outside what the issue reported.


Reviewed by anthropic/claude-opus-5-5 and openai/gpt-6.1-sol.

Comment thread .changeset/quiet-404-rewrite-cache.md Outdated
"emdash": patch
---

Fixes repeated layout queries when anonymous public pages use `Astro.rewrite("/404")`. Rewritten pages with the same locale and rendering policy reuse the request cache and prefetched layout data instead of opening a second database scope.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[suggestion] Two parts of this entry won't mean much to someone reading the CHANGELOG:

  • "Rendering policy" is internal shorthand.
  • "Opening a second database scope" describes how the fix works, not what users see.

The fix also isn't limited to /404: it applies to any Astro.rewrite() target on an anonymous public page. A reader decides whether this release affects them by asking whether they rewrite to an error page and see doubled D1 queries. Here's a suggested rewrite:

Suggested change
Fixes repeated layout queries when anonymous public pages use `Astro.rewrite("/404")`. Rewritten pages with the same locale and rendering policy reuse the request cache and prefetched layout data instead of opening a second database scope.
Fixes anonymous public pages that call `Astro.rewrite()` (for example, `Astro.rewrite("/404")` for an unknown slug) running every layout query twice. The rewritten page now reuses the original request's cached reads and prefetched layout data (site settings, menus, collection reads), so it costs about as many database round trips as requesting the target directly. Previews, edit mode, signed-in requests, and rewrites that change locale still render with a fresh request context.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reworded the changeset to describe duplicate layout queries for anonymous Astro.rewrite() calls, with /404 as an example rather than the only target. It now states the exclusions in user-facing terms and avoids claiming D1 round-trip totals we haven't reproduced.

@pkg-pr-new

pkg-pr-new Bot commented Nov 12, 2026 •

Copy link
Copy Markdown

Open in StackBlitz

@emdash-cms/admin

npm i https://pkg.pr.new/@emdash-cms/admin@4840

@emdash-cms/auth

npm i https://pkg.pr.new/@emdash-cms/auth@4840

@emdash-cms/auth-atproto

npm i https://pkg.pr.new/@emdash-cms/auth-atproto@4840

@emdash-cms/blocks

npm i https://pkg.pr.new/@emdash-cms/blocks@4840

@emdash-cms/cloudflare

npm i https://pkg.pr.new/@emdash-cms/cloudflare@4840

@emdash-cms/contentful-to-portable-text

npm i https://pkg.pr.new/@emdash-cms/contentful-to-portable-text@4840

emdash

npm i https://pkg.pr.new/emdash@4840

create-emdash

npm i https://pkg.pr.new/create-emdash@4840

@emdash-cms/gutenberg-to-portable-text

npm i https://pkg.pr.new/@emdash-cms/gutenberg-to-portable-text@4840

@emdash-cms/plugin-cli

npm i https://pkg.pr.new/@emdash-cms/plugin-cli@4840

@emdash-cms/plugin-test

npm i https://pkg.pr.new/@emdash-cms/plugin-test@4840

@emdash-cms/plugin-types

npm i https://pkg.pr.new/@emdash-cms/plugin-types@4840

@emdash-cms/registry-client

npm i https://pkg.pr.new/@emdash-cms/registry-client@4840

@emdash-cms/registry-lexicons

npm i https://pkg.pr.new/@emdash-cms/registry-lexicons@4840

@emdash-cms/registry-loader

npm i https://pkg.pr.new/@emdash-cms/registry-loader@4840

@emdash-cms/registry-moderation

npm i https://pkg.pr.new/@emdash-cms/registry-moderation@4840

@emdash-cms/registry-verification

npm i https://pkg.pr.new/@emdash-cms/registry-verification@4840

upgrade-emdash

npm i https://pkg.pr.new/upgrade-emdash@4840

@emdash-cms/sandbox-workerd

npm i https://pkg.pr.new/@emdash-cms/sandbox-workerd@4840

@emdash-cms/x402

npm i https://pkg.pr.new/@emdash-cms/x402@4840

@emdash-cms/plugin-ai-moderation

npm i https://pkg.pr.new/@emdash-cms/plugin-ai-moderation@4840

@emdash-cms/plugin-ai-search

npm i https://pkg.pr.new/@emdash-cms/plugin-ai-search@4840

@emdash-cms/plugin-atproto

npm i https://pkg.pr.new/@emdash-cms/plugin-atproto@4840

@emdash-cms/plugin-audit-log

npm i https://pkg.pr.new/@emdash-cms/plugin-audit-log@4840

@emdash-cms/plugin-color

npm i https://pkg.pr.new/@emdash-cms/plugin-color@4840

@emdash-cms/plugin-embeds

npm i https://pkg.pr.new/@emdash-cms/plugin-embeds@4840

@emdash-cms/plugin-field-kit

npm i https://pkg.pr.new/@emdash-cms/plugin-field-kit@4840

@emdash-cms/plugin-forms

npm i https://pkg.pr.new/@emdash-cms/plugin-forms@4840

@emdash-cms/plugin-webhook-notifier

npm i https://pkg.pr.new/@emdash-cms/plugin-webhook-notifier@4840

commit: ef9220d

Addressed the reviewer’s changeset suggestion: describe duplicate layout queries for anonymous Astro.rewrite() calls, use /404 as an example rather than the only target, and remove internal rendering-policy/database-scope terminology. Runtime source is unchanged from the approved candidate. pnpm format, diff checks, and 92 focused tests pass. Pre-submit review found no blocking defect; conservative scope exclusions and lack of exact D1 measurements remain disclosed.

EmDash-Bot-Case: 1198246700-issue-6360825959
EmDash-Bot-Candidate: cand-2-52930f7a59

@emdashbot emdashbot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The approach is sound. During Astro.rewrite(), middleware is re-entered with the same locals. A locals marker detects this, and the runtime middleware passes straight through. The rewritten render then reuses the warmed request cache and layout prefetch, while the outer render keeps ownership of prefetch, metrics, finalization and scoped-DB cleanup. Both reviewers approved and found nothing new to fix. The earlier changeset wording suggestion is resolved: it now describes anonymous Astro.rewrite() calls in user-facing terms and makes no unsupported D1 query-count claims. Neither reviewer reproduced the reporter's D1 query numbers. One reviewer noted that rewrites on the authenticated path still open a second scope. That is outside what the issue reported.


Reviewed by anthropic/claude-opus-5-5 and openai/gpt-6.1-sol.

@cloudflare-workers-and-pages

Copy link
Copy Markdown

🚀 Deploying Preview to Cloudflare 🚀

Preview URL: https://emdash-bot-issue-4839.try.emdashcms.com, https://emdash-bot-issue-4839-emdash-playground.emdash-cms.workers.dev (commit ef9220d)

This URL reflects your latest Preview deployment

Preview Deployments by commit

Status Deployment URL Commit Updated (UTC) See this deployment's details
  • Build: Success ✅
  • Deployment: Success ✅

View logs ↗
https://babb6d00.try.emdashcms.com, https://babb6d00-emdash-playground.emdash-cms.workers.dev ef9220d 2026-11-12T23:40:44.086Z Visit the dashboard ↗

@emdash-autofix emdash-autofix Bot added triage/awaiting-reporter Fix pushed, waiting on reporter to verify and removed triage/awaiting-reporter Fix pushed, waiting on reporter to verify labels Nov 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/core bot:fix Assign this issue or pull request to the EmDash bot to fix cla: signed size/L triage/awaiting-reporter Fix pushed, waiting on reporter to verify

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Astro.rewrite("/404") repeats every layout query: the request cache and prefetch are not reused

0 participants