{"record":{"id":"9175c9b3c641876d","repo":"remix-run/react-router","slug":"cannot-call-runclientmiddleware-from-within-an","errorCode":null,"errorMessage":"Cannot call `runClientMiddleware()` from within an `runClientMiddleware` handler","messagePattern":"Cannot call `runClientMiddleware\\(\\)` from within an `runClientMiddleware` handler","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/react-router/lib/router/router.ts","lineNumber":6567,"sourceCode":"  };\n  let runClientMiddleware = isStaticHandler\n    ? () => {\n        throw new Error(\n          \"You cannot call `runClientMiddleware()` from a static handler \" +\n            \"`dataStrategy`. Middleware is run outside of `dataStrategy` during \" +\n            \"SSR in order to bubble up the Response.  You can enable middleware \" +\n            \"via the `respond` API in `query`/`queryRoute`\",\n        );\n      }\n    : (cb: DataStrategyFunction<RouterContextProvider>) => {\n        let typedDataStrategyArgs =\n          dataStrategyArgs as DataStrategyFunctionArgs<RouterContextProvider>;\n        return runClientMiddlewarePipeline(typedDataStrategyArgs, () => {\n          return cb({\n            ...typedDataStrategyArgs,\n            fetcherKey,\n            runClientMiddleware: () => {\n              throw new Error(\n                \"Cannot call `runClientMiddleware()` from within an \" +\n                  \"`runClientMiddleware` handler\",\n              );\n            },\n          });\n        });\n      };\n\n  let results = await dataStrategyImpl({\n    ...dataStrategyArgs,\n    fetcherKey,\n    runClientMiddleware,\n  });\n\n  // Wait for all routes to load here but swallow the error since we want\n  // it to bubble up from the `await loadRoutePromise` in `callLoaderOrAction` -\n  // called from `match.resolve()`. We also ensure that all promises are\n  // awaited so that we don't inadvertently leave any hanging promises.","sourceCodeStart":6549,"sourceCodeEnd":6585,"githubUrl":"https://github.com/remix-run/react-router/blob/7aea711dd1ae2bc5a076d13ff17291829690fa74/packages/react-router/lib/router/router.ts#L6549-L6585","documentation":"The callback you pass to runClientMiddleware(cb) receives args whose runClientMiddleware is intentionally a throwing stub (lib/router/router.ts:6588): nesting is disallowed because the outer call is already driving the middleware pipeline for this request/fetcher scope.","triggerScenarios":"Inside args.runClientMiddleware(async (ctx) => { ... }), calling ctx.runClientMiddleware(...) (or the outer one captured earlier) again for a nested fetch; recursive helper functions that wrap each level in runClientMiddleware.","commonSituations":"Composing several middleware-wrapped operations in one dataStrategy; generic wrappers (tracing, auth refresh) applied at multiple layers of the same call tree.","solutions":["Flatten the logic: make a single runClientMiddleware call at the top of your dataStrategy","Move shared inner work into plain functions that take args, not into another middleware pipeline","Delete the nested wrapper call and reuse the result of the single outer call"],"exampleFix":"// before\nargs.runClientMiddleware(async (a) => {\n  return a.runClientMiddleware(async () => doWork(a)) // throws\n})\n// after\nargs.runClientMiddleware(async (a) => doWork(a))","handlingStrategy":"validation","validationCode":"// Structural rule: call runClientMiddleware once per (request, fetcherKey) scope\nlet wrapped = false;\nconst dataStrategy = async (args) => {\n  if (!wrapped) { wrapped = true; return args.runClientMiddleware(() => doWork(args)) }\n  return doWork(args);\n};","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Make exactly one runClientMiddleware call at the top of your dataStrategy","Factor inner layers into plain functions receiving args instead of nested pipelines","Review wrappers (tracing/auth) applied at multiple layers of the same call tree"],"tags":["middleware","datastrategy","nesting","api-misuse"],"backgroundTag":"middleware-nested-invocation","analyzedSha":"7aea711dd1ae2bc5a076d13ff17291829690fa74","analyzedAt":"2026-08-18T18:04:14.938Z","contentChangedAt":"2026-08-18T18:04:14.938Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}