{"record":{"id":"f921ca793bb24883","repo":"withastro/astro","slug":"fetchstate-not-found-on-apicontext-this-is-an-int","errorCode":null,"errorMessage":"FetchState not found on APIContext. This is an internal error — the context was not created through Astro's request pipeline.","messagePattern":"FetchState not found on APIContext\\. This is an internal error — the context was not created through Astro's request pipeline\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/astro/src/core/fetch/fetch-state.ts","lineNumber":139,"sourceCode":"\tstatus: number;\n\n\t/**\n\t * Triggers a rewrite to a different route.\n\t *\n\t * [Astro reference](https://docs.astro.build/en/guides/routing/#rewrites)\n\t */\n\trewrite(payload: RewritePayload): Promise<Response>;\n}\n\n/**\n * Retrieves the `FetchState` stashed on an `APIContext` by\n * `FetchState.getAPIContext()`. Throws if not found — this indicates\n * the context was not created through Astro's request pipeline.\n */\nexport function getFetchStateFromAPIContext(context: APIContext): FetchState {\n\tconst state = (context as any)[fetchStateSymbol] as FetchState | undefined;\n\tif (!state) {\n\t\tthrow new Error(\n\t\t\t\"FetchState not found on APIContext. This is an internal error — the context was not created through Astro's request pipeline.\",\n\t\t);\n\t}\n\treturn state;\n}\n\n/**\n * Holds per-request state as it flows through the handler pipeline.\n *\n * **This class is user-facing** via `astro/fetch` and `astro/hono`.\n * The {@link AstroFetchState} interface defines the stable public\n * surface. Members not on that interface are internal and\n * may change without notice.\n *\n * Performance note: fields on this class are plain properties — ES\n * private fields (`#foo`) have a non-zero per-access cost in V8\n * which is measurable on the hot render path, so `#` is used only\n * for rarely-accessed memoized caches and Maps.","sourceCodeStart":121,"sourceCodeEnd":157,"githubUrl":"https://github.com/withastro/astro/blob/e294953aa8aadd98d5be92e60a03037b05dbdfd4/packages/astro/src/core/fetch/fetch-state.ts#L121-L157","documentation":"Astro's request pipeline stashes a per-request FetchState on the APIContext under a module-private symbol (fetchStateSymbol). getFetchStateFromAPIContext() reads that symbol and throws this error when it is absent, meaning the context object was never created through Astro's request pipeline (FetchState.getAPIContext / app.render). It is an internal invariant violation, not a configuration problem: either someone hand-built an APIContext, or two copies of Astro core are running and the symbol from one copy is not found by the other.","triggerScenarios":"An internal helper that expects a pipeline-created context receives one built by hand or by a third party: a custom adapter calling Astro internals with its own fabricated context object, a unit test constructing an APIContext literal, or duplicate astro package instances in node_modules (e.g. pnpm resolving two versions) so fetchStateSymbol differs between the stamper and the reader.","commonSituations":"Writing a custom adapter or integration that builds its own context instead of delegating to Astro's handler; unit tests that fake an APIContext; monorepos where several @astrojs/* integrations pin different astro versions, loading astro core twice; mixing a locally linked astro with a registry-installed one.","solutions":["Route requests through Astro's own pipeline (app.render / the built server entry) instead of passing a hand-made context into Astro internals","If you write an adapter, delegate rendering to Astro's handler so contexts are stamped by FetchState, never construct APIContext yourself","In tests, use the built server entry or Astro's official test utilities rather than fabricating contexts","Check for duplicate astro copies (pnpm why astro / npm ls astro) and dedupe with version overrides so the symbol module is loaded once","If every party involved is first-party Astro code, report it as an Astro bug with a reproduction"],"exampleFix":"// before (custom adapter)\nconst context = { request, params: {}, locals: {} } as APIContext;\nawait someAstroInternal(context);\n\n// after — let Astro create the context via its pipeline\nconst response = await app.render(request);","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  // call the Astro internal that needs the pipeline context\n} catch (err) {\n  if (err instanceof Error && err.message.includes('FetchState not found on APIContext')) {\n    throw new Error('Context was not created by the Astro request pipeline — pass requests through app.render()', { cause: err });\n  }\n  throw err;\n}","preventionTips":["Never hand-construct an APIContext; let Astro's pipeline create it via app.render or the built server entry","Adapters and integrations should delegate to Astro's handler instead of synthesizing contexts","Dedupe astro in the lockfile (pnpm overrides / resolutions) so the symbol module loads once","In tests, drive the built server entry rather than fabricating context objects"],"tags":["internal","api-context","fetch-state","request-pipeline","duplicate-packages"],"backgroundTag":"missing-framework-context","analyzedSha":"e294953aa8aadd98d5be92e60a03037b05dbdfd4","analyzedAt":"2026-08-18T18:48:03.901Z","contentChangedAt":"2026-08-18T18:48:03.901Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}