router icon indicating copy to clipboard operation
router copied to clipboard

Start: "Invalid lazy handler result" when srcDirectory is root

Open djgrant opened this issue 7 months ago • 1 comments

Which project does this relate to?

Start

Describe the bug

When tsr.srcDirectory is set to . server routes and redirects trigger a nitro error "Invalid lazy handler result".

In browser:

{
  "error": true,
  "url": "http://[::]:3000/",
  "statusCode": 500,
  "statusMessage": "Server Error",
  "message": "Server Error"
}

In server logs:

[request error] [unhandled] [GET] https://5jd49m-3000.csb.app/
 TypeError: Invalid lazy handler result. It should be a function:
    at file:///project/workspace/.output/server/index.mjs:1473:17
    at async Object.handler (file:///project/workspace/.output/server/index.mjs:1557:19)
    at async Server.toNodeHandle (file:///project/workspace/.output/server/index.mjs:1828:7) {
  cause: TypeError: Invalid lazy handler result. It should be a function:
      at file:///project/workspace/.output/server/index.mjs:1473:17
      at async Object.handler (file:///project/workspace/.output/server/index.mjs:1557:19)
      at async Server.toNodeHandle (file:///project/workspace/.output/server/index.mjs:1828:7),
  statusCode: 500,
  fatal: false,
  unhandled: true,
  statusMessage: undefined,
  data: undefined
}

Note: this works ok in dev. It is only triggered by building and running a server (tested with node-server and aws-lambda targets).

Your Example Website or App

https://codesandbox.io/p/github/djgrant/repro-tanstack-start/invalid-lazy-handler

Steps to Reproduce the Bug or Issue

  1. Open sandbox
  2. Run npm run build
  3. Run node .output/server/index.mjs
  4. Open preview
  5. Observe output

Expected behavior

Server routes should not trigger this error.

Screenshots or Videos

No response

Platform

Any

Additional context

No response

djgrant avatar Jun 15 '25 20:06 djgrant

I was able to work around this issue by adding this to nitro.config.ts:

export default defineNitroConfig({
  // prevent nitro picking up tanstack routes
  // https://github.com/TanStack/router/issues/4432
  apiDir: "non-existent-dir",
  routesDir: "non-existent-dir",
});

This prevents the nitro build from adding tanstack routes to its collection of event handlers.

@schiller-manuel I think this is indirectly caused by this setting https://github.com/TanStack/router/blob/main/packages/start-plugin-core/src/nitro-plugin/plugin.ts#L79. By default, nitro processes file routes in ${baseUrl}/routes, so if your tanstack srcDirectory is ., ./routes becomes a target for both tanstack and nitro.

It might be an idea to add some new defaults like:

{
  apiDir: "nitro/api",
  routesDir: "nitro/routes"
}

djgrant avatar Jun 17 '25 09:06 djgrant

we dont uses nitro internally anymore in start.

schiller-manuel avatar Oct 06 '25 23:10 schiller-manuel