{"record":{"id":"3bb59f3bf6da7839","repo":"withastro/astro","slug":"middlewarenodataornextcalled","errorCode":"MiddlewareNoDataOrNextCalled","errorMessage":"Make sure your middleware returns a `Response` object, either directly or by returning the `Response` from calling the `next` function.","messagePattern":"Make sure your middleware returns a `Response` object, either directly or by returning the `Response` from calling the `next` function\\.","errorType":"exception","errorClass":"AstroError","httpStatus":null,"severity":"error","filePath":"packages/astro/src/core/middleware/callMiddleware.ts","lineNumber":96,"sourceCode":"\t\t\t\treturn value;\n\t\t\t} else {\n\t\t\t\t/**\n\t\t\t\t * Here we handle the case where `next` was called and returned nothing.\n\t\t\t\t */\n\t\t\t\tif (responseFunctionPromise) {\n\t\t\t\t\treturn responseFunctionPromise;\n\t\t\t\t} else {\n\t\t\t\t\tthrow new AstroError(AstroErrorData.MiddlewareNotAResponse);\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (typeof value === 'undefined') {\n\t\t\t/**\n\t\t\t * There might be cases where `next` isn't called and the middleware **must** return\n\t\t\t * something.\n\t\t\t *\n\t\t\t * If not thing is returned, then we raise an Astro error.\n\t\t\t */\n\t\t\tthrow new AstroError(AstroErrorData.MiddlewareNoDataOrNextCalled);\n\t\t} else if (value instanceof Response === false) {\n\t\t\tthrow new AstroError(AstroErrorData.MiddlewareNotAResponse);\n\t\t} else {\n\t\t\t// Middleware did not call resolve and returned a value\n\t\t\treturn value;\n\t\t}\n\t});\n}\n","sourceCodeStart":78,"sourceCodeEnd":105,"githubUrl":"https://github.com/withastro/astro/blob/d081033d5fe8e8a68c4bbbad4af9d2deb9c74bca/packages/astro/src/core/middleware/callMiddleware.ts#L78-L105","documentation":"Thrown when middleware neither called next() nor returned any value. A middleware must do at least one: call next() to delegate to the next handler/page, or return a Response. Returning undefined without calling next leaves Astro with nothing to render.","triggerScenarios":"A middleware that does work (sets locals, logs) and ends without `return next()` or any return statement. The `else if (typeof value === 'undefined')` branch at line 96 of callMiddleware.ts catches this.","commonSituations":"Forgetting to add `return next()` after early logic; a conditional branch that forgets to call next in the fall-through case; refactoring a handler and dropping the final next call.","solutions":["End every middleware with `return next()` unless intentionally returning a Response.","Audit conditional branches to ensure each path either returns a Response or calls next.","Use defineMiddleware() so TypeScript guides the return type."],"exampleFix":"// before\nexport const onRequest = async (ctx, next) => {\n  ctx.locals.time = Date.now();\n};\n\n// after\nexport const onRequest = async (ctx, next) => {\n  ctx.locals.time = Date.now();\n  return next();\n};","handlingStrategy":"validation","validationCode":"// Every code path must call next() or return a Response.\nexport const onRequest = async (ctx, next) => {\n  ctx.locals.t = Date.now();\n  return next(); // mandatory terminator\n};","typeGuard":"// Middleware must yield a Response or delegate via next.\nfunction middlewareTerminates(value: unknown, nextCalled: boolean): boolean {\n  return nextCalled || value instanceof Response;\n}","tryCatchPattern":"try {\n  await callMiddleware(handler, ctx, render);\n} catch (e) {\n  if (e instanceof Error && /returns a .Response./i.test(e.message)) {\n    // middleware forgot to return next(); add it\n  }\n  throw e;\n}","preventionTips":["End every middleware branch with `return next()` unless returning a Response.","Audit conditional branches for missing terminators.","Type middleware handlers with MiddlewareHandler to surface gaps."],"tags":["middleware","response","ssr","lifecycle"],"backgroundTag":null,"analyzedSha":"d081033d5fe8e8a68c4bbbad4af9d2deb9c74bca","analyzedAt":"2026-08-12T13:37:29.035Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}