This specification is maintained by the AgentRules Working Group. Have enhancements or want to claim maintainership?Submit Specification →
frontendcritical PriorityID: nextjs-15-async-request-context-memoization-isolation

Next.js 15 Async Request Context & Request-Memoization Tenant Isolation

Enforces strict execution boundary isolation for Next.js 15 React Server Components (RSC) and React 19 request memoization. Prohibits floating unawaited microtasks, global mutable tenant storage, and un-isolated React.cache usage that corrupts AsyncLocalStorage context across concurrent streaming boundaries.

Prohibited Anti-Pattern: Leaking Cross-Tenant Context via Detached Microtasks and Module-Level State in RSC Streaming

Export Ready-to-Drop Configuration

Select format below to copy code or download file directly.

---
description: Next.js 15 Async Request Context & Request-Memoization Tenant Isolation - Enforces strict execution boundary isolation for Next.js 15 React Server Components (RSC) and React 19 request memoization. Prohibits floating unawaited microtasks, global mutable tenant storage, and un-isolated React.cache usage that corrupts AsyncLocalStorage context across concurrent streaming boundaries.
globs: app/**/*.{ts,tsx}, src/**/*.{ts,tsx}, lib/**/*.{ts,tsx}
alwaysApply: true
verified_by: "agentrules.org"
license: "CC-BY-4.0"
source: "https://agentrules.org/rules/nextjs-15-async-request-context-memoization-isolation"
---

# Next.js 15 Async Request Context & Request-Memoization Tenant Isolation

> **Severity**: CRITICAL | **Category**: frontend
> **Anti-Pattern Warning**: Leaking Cross-Tenant Context via Detached Microtasks and Module-Level State in RSC Streaming

## System Constraints
You are a Principal Software Architect enforcing runtime context integrity and tenant isolation in Next.js 15 App Router and React 19 Server Components. Mandate strict adherence to AsyncLocalStorage lifecycle constraints. Under concurrent RSC streaming, asynchronous operations that escape the awaiting boundary of a request worker forfeit their AsyncLocalStorage bindings, causing catastrophic cross-tenant context bleeding, silent cache contamination via React.cache, or unhandled store termination errors. Enforce bounded promise scopes, explicit context propagation, and Next.js 15's after() API for post-response tasks.

## Strict Guidelines
- Engineers MUST NEVER initiate fire-and-forget unawaited promises (e.g., `void doTask()` or floating `fetch()`) inside Server Components, Server Actions, or Route Handlers.
- Engineers MUST ALWAYS schedule secondary asynchronous work executed outside the render lifecycle using Next.js 15's `after()` from 'next/server' to guarantee request context preservation or cleanly decoupled cleanup.
- Engineers MUST NEVER store tenant IDs, authentication states, or request-specific parameters in module-level global variables or closure-persisted singletons.
- Code MUST ALWAYS pass tenant identity and auth tokens as explicit parameters to memoized functions wrapped in `React.cache()`; memoized functions MUST NOT rely solely on implicit ambient context when invoked across async microtask yields.
- Services MUST NEVER access `headers()`, `cookies()`, or request-scoped stores inside `setTimeout`, `setInterval`, raw microtasks (`queueMicrotask`), or unawaited background threads.
- Components NEVER render asynchronously without awaiting all child promises or correctly encapsulating streaming sub-trees with `<Suspense>` boundaries to ensure React concurrent fiber trees preserve distinct AsyncLocalStorage contexts.

## Bad vs Good Implementations
### Asynchronous Telemetry & Request Memoization with Tenant Isolation

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: Accessing ambient headers() within an unawaited floating IIFE causes unpredictable AsyncLocalStorage detachment during RSC streaming. In high-concurrency environments, the worker continues execution after the streaming chunk renders, potentially inheriting a subsequent request's context or throwing a store-teardown exception. Additionally, React.cache without explicit parameter inputs risks returning poisoned cached data if context resolution shifts.
```typescript
import { headers } from 'next/headers';
import { cache } from 'react';

// ANTI-PATTERN: Module-level cache without explicit tenant parameter in key signature
export const getTenantSettings = cache(async () => {
  const reqHeaders = await headers(); // Implicit dynamic ambient lookup
  const tenantId = reqHeaders.get('x-tenant-id') || 'default';
  return db.settings.findUnique({ where: { tenantId } });
});

export default async function TenantDashboard() {
  const settings = await getTenantSettings();

  // ANTI-PATTERN: Floating unawaited promise during RSC streaming.
  // AsyncLocalStorage context will leak into sibling workers or crash when store is torn down.
  void (async () => {
    const reqHeaders = await headers(); // Likely corrupted or throws: Dynamic server usage / store missing
    await db.auditLog.create({
      data: { tenantId: reqHeaders.get('x-tenant-id'), action: 'VIEW_DASHBOARD' }
    });
  })();

  return <div>Tenant: {settings.name}</div>;
}
```

#### Production Standard (Correct)
> **Standard**: Tenant identification is explicitly extracted within the guarded execution lifecycle and passed into `React.cache(tenantId)`, eliminating cross-tenant collision. Asynchronous work intended to execute out-of-band is explicitly delegated to Next.js 15's `after()` API, preserving async isolation and preventing unhandled microtask leakage across streaming responses.
```typescript
import { headers } from 'next/headers';
import { after } from 'next/server';
import { cache } from 'react';

// SECURE: Memoized per explicit tenantId parameter preventing cross-tenant cache hits
export const getTenantSettings = cache(async (tenantId: string) => {
  return db.settings.findUnique({ where: { tenantId } });
});

export default async function TenantDashboard() {
  const reqHeaders = await headers();
  const tenantId = reqHeaders.get('x-tenant-id');
  if (!tenantId) {
    throw new Error('Tenant context missing from request headers.');
  }

  const settings = await getTenantSettings(tenantId);

  // SECURE: Next.js 15 `after()` safely extends execution beyond response streaming
  // without leaking unawaited microtask states into concurrent request lifecycles
  after(async () => {
    await db.auditLog.create({
      data: { tenantId, action: 'VIEW_DASHBOARD', timestamp: new Date() }
    });
  });

  return <div>Tenant: {settings.name}</div>;
}
```

Architectural Specification & Invariant Rationale

Architectural Invariant Design: Next.js 15 Async Request Context & Request-Memoization Tenant Isolation

Next.js 15 Async Request Context & Request-Memoization Tenant Isolation defines an industrial-grade behavioral standard for frontend engineering. Enforces strict execution boundary isolation for Next.js 15 React Server Components (RSC) and React 19 request memoization. Prohibits floating unawaited microtasks, global mutable tenant storage, and un-isolated React.cache usage that corrupts AsyncLocalStorage context across concurrent streaming boundaries. Modern software architectures require strict adherence to deterministic patterns to guarantee high availability, maintainability, and zero security vulnerabilities.

Framework Paradigm Shift & Drift MechanicsLLMs are trained on millions of open-source repositories containing outdated code, legacy idioms, and unpatched antipatterns. When coding assistants generate implementations for this stack, they default to common statistical tokens: Leaking Cross-Tenant Context via Detached Microtasks and Module-Level State in RSC Streaming Without an explicit system instruction file, developers spend hours debugging silent failures.
Failure Modes & Production Blast Radius

Hazard Analysis: What Breaks Without This Rule

The following failure modes have been cataloged from hundreds of hours of production code reviews where AI assistants produced non-compliant implementations:

Failure ModeAI Symptom (The Anti-Pattern)SeverityProduction Impact & Remedy
AI Hallucination & Deprecation DriftLeaking Cross-Tenant Context via Detached Microtasks and Module-Level State in RSC StreamingCritical
Violating this industrial standard introduces regression bugs, security risks, and unexpected runtime failures in production.
Enforce explicit behavioral system directives across all AI coding assistants in your repository.
Silent Architecture InconsistencyAI assistants produce mixed paradigms across files, creating fragmented codebase conventions.Medium
Increases cognitive load during code reviews and leads to maintenance debt across engineering teams.
Pin project conventions in .cursor/rules, CLAUDE.md, and AGENTS.md so all team agents follow identical guardrails.
Architectural Directives in Detail

Step-by-Step Production Directives

Each rule constraint below is injected into the AI agent's system prompt to establish deterministic boundaries:

1

Engineers MUST NEVER initiate fire-and-forget unawaited promises (e.g., `void doTask()` or floating `fetch()`) inside Server Components, Server Actions, or Route Handlers.

Engineers MUST NEVER initiate fire-and-forget unawaited promises (e.g., `void doTask()` or floating `fetch()`) inside Server Components, Server Actions, or Route Handlers.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
2

Engineers MUST ALWAYS schedule secondary asynchronous work executed outside the render lifecycle using Next.js 15's `after()` from 'next/server' to guarantee request context preservation or cleanly decoupled cleanup.

Engineers MUST ALWAYS schedule secondary asynchronous work executed outside the render lifecycle using Next.js 15's `after()` from 'next/server' to guarantee request context preservation or cleanly decoupled cleanup.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
3

Engineers MUST NEVER store tenant IDs, authentication states, or request-specific parameters in module-level global variables or closure-persisted singletons.

Engineers MUST NEVER store tenant IDs, authentication states, or request-specific parameters in module-level global variables or closure-persisted singletons.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
4

Code MUST ALWAYS pass tenant identity and auth tokens as explicit parameters to memoized functions wrapped in `React.cache()`

Code MUST ALWAYS pass tenant identity and auth tokens as explicit parameters to memoized functions wrapped in `React.cache()`; memoized functions MUST NOT rely solely on implicit ambient context when invoked across async microtask yields.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
5

Services MUST NEVER access `headers()`, `cookies()`, or request-scoped stores inside `setTimeout`, `setInterval`, raw microtasks (`queueMicrotask`), or unawaited background threads.

Services MUST NEVER access `headers()`, `cookies()`, or request-scoped stores inside `setTimeout`, `setInterval`, raw microtasks (`queueMicrotask`), or unawaited background threads.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
6

Components NEVER render asynchronously without awaiting all child promises or correctly encapsulating streaming sub-trees with `<Suspense>` boundaries to ensure React concurrent fiber trees preserve distinct AsyncLocalStorage contexts.

Components NEVER render asynchronously without awaiting all child promises or correctly encapsulating streaming sub-trees with `<Suspense>` boundaries to ensure React concurrent fiber trees preserve distinct AsyncLocalStorage contexts.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
Technical Questions & Answers

Frequently Asked Technical Questions

Common questions developers face when configuring AI coding assistants for this stack:

Q:Why is Next.js 15 Async Request Context & Request-Memoization Tenant Isolation critical for AI coding assistants?

Enforces strict execution boundary isolation for Next.js 15 React Server Components (RSC) and React 19 request memoization. Prohibits floating unawaited microtasks, global mutable tenant storage, and un-isolated React.cache usage that corrupts AsyncLocalStorage context across concurrent streaming boundaries. Without explicit behavioral boundaries, AI coding assistants (Cursor, Claude Code, Windsurf, Codex) rely on training data averages, which frequently produce deprecated, inefficient, or vulnerable code patterns.

Q:How does adopting this rule prevent AI hallucinations?

This rule explicitly declares what the AI must avoid (Leaking Cross-Tenant Context via Detached Microtasks and Module-Level State in RSC Streaming) and prescribes verified positive examples. Grounding the LLM with negative and positive pairs eliminates guesswork.

Q:Which AI coding environments are supported?

This specification is multi-platform compatible: Cursor (.cursor/rules/*.mdc & .cursorrules), Anthropic Claude Code (CLAUDE.md), Windsurf (.windsurfrules), Codex / Cline (AGENTS.md), and GitHub Copilot (.github/copilot-instructions.md).

Q:Can I combine this rule with other technology stacks?

Yes. Use the Interactive Stack Builder or download an Agent Pack to merge this rule with other frontend, backend, database, security, and DevOps rules without syntax collision.

Open Specification · CC BY 4.0·Free for Personal, Team & Commercial In-Repo Use

Citation & Open Source Attribution Guidelines

This specification is licensed under Creative Commons Attribution 4.0 International (CC BY 4.0). You are completely free to adapt and share this rule in your workspace. If citing, including in public AI benchmark datasets, or redistributing, attribution to AgentRules.org is required.

Related FRONTEND Rules

View all rules →
frontend
119

SolidStart 1.0 Server Functions & Async Boundaries Production Standard

SolidStart 1.0 relies on the Vinxi bundler to split `server$` closures into independent HTTP POST RPC endpoints. Direct lexical closure over client signals within `server$` scopes or failure to demarcate async boundaries with `<Suspense>` causes silent serialization failures, client-bundle secret leaks, and SSR hydration mismatches. Enforcing strict parameter passing, runtime input validation, and Solid async primitives maintains security and fine-grained reactivity across network boundaries.

frontend
119

Astro 5 Actions & Content Layer Production Standard

Enforces strict type safety and architectural correctness for Astro 5 Server Actions and the zero-waterfall Content Layer API. Prevents runtime contract mismatches, hydration mismatches, and unhandled mutation exceptions across dynamic and prerendered boundaries. Failure to follow these patterns leads to silent data fetching waterfalls, build-time cache corruptions, and unhandled server action exceptions.

frontend
51

Nuxt 4 Nitro Server Engine & Shared Directory Production Standard

Nuxt 4 enforces strict boundary segregation between client UI in the app/ directory, backend endpoints in server/, and universal contracts in shared/. Violating cross-boundary isolation or maintaining module-scoped state in Nitro server handlers causes catastrophic cross-request data corruption and hydration mismatches under concurrent production traffic. Architects must enforce request-isolated H3 event contexts, universal serialization schemas, and strict path-alias boundaries.

1 Rule in Stack

Next.js