Single Fetch: returning `null` from resource route loader leads to error
Reproduction
https://stackblitz.com/edit/remix-run-remix-xsdwha?file=app%2Froutes%2F_index.tsx
Just this triggers it when you don't have a default export (making it a resource route)
export const loader = async () => {
return null;
};
System Info
System:
OS: macOS 14.0
CPU: (10) arm64 Apple M1 Pro
Memory: 62.27 MB / 32.00 GB
Shell: 3.6.1 - /usr/local/bin/fish
Binaries:
Node: 20.11.0 - ~/.volta/tools/image/node/20.11.0/bin/node
npm: 10.2.4 - ~/.volta/tools/image/node/20.11.0/bin/npm
Browsers:
Chrome: 120.0.6099.109
Safari: 17.0
npmPackages:
@remix-run/dev: ^2.9.2 => 2.9.2
@remix-run/eslint-config: ^2.9.2 => 2.9.2
@remix-run/node: ^2.9.2 => 2.9.2
@remix-run/react: ^2.9.2 => 2.9.2
@remix-run/serve: ^2.9.2 => 2.9.2
vite: ^5.2.11 => 5.2.11
Used Package Manager
npm
Expected Behavior
It does not error.
Actual Behavior
Seeing this in Stackblitz:
Unexpected Server Error
TypeError: response is not an Object. (evaluating 'router.UNSAFE_DEFERRED_SYMBOL in response')
Seeing this locally (node v20)
[remix] TypeError: Cannot use 'in' operator to search for 'Symbol(deferred)' in null
[remix] at handleResourceRequest (/Users/chrismcc/workspace/atlas/node_modules/@remix-run/server-runtime/dist/server.js:371:60)
[remix] at async requestHandler (/Users/chrismcc/workspace/atlas/node_modules/@remix-run/server-runtime/dist/server.js:138:18)
[remix] at async nodeHandler (/Users/chrismcc/workspace/atlas/node_modules/@remix-run/dev/dist/vite/plugin.js:841:27)
[remix] at async /Users/chrismcc/workspace/atlas/node_modules/@remix-run/dev/dist/vite/plugin.js:844:15
Looks like this stems from this because typeof null === 'object: https://github.com/remix-run/remix/blob/2e65318b15df407b31b101362e03729e61ec5622/packages/remix-server-runtime/server.ts#L594-L600
Hitting this as well when trying to use unstable_singleFetch. Using the json wrapper doesn't work either, as return json(null) gives a typescript error:
Argument of type '({ request }: LoaderArgs) => Promise<TypedResponse<null>>' is not assignable to parameter of type 'Loader'.
Type 'Promise<TypedResponse<null>>' is not assignable to type 'MaybePromise<DataFunctionReturnValue>'.
Type 'Promise<TypedResponse<null>>' is not assignable to type '{ [key: string]: Serializable; [key: number]: Serializable; [key: symbol]: Serializable; } | Map<Serializable, Serializable> | Set<...> | Promise<...> | Promise<...>'.
Type 'Promise<TypedResponse<null>>' is not assignable to type 'Promise<Serializable>'.
Type 'TypedResponse<null>' is not assignable to type 'Serializable'.
Type 'TypedResponse<null>' is not assignable to type '{ [key: string]: Serializable; [key: number]: Serializable; [key: symbol]: Serializable; }'.
Property 'headers' is incompatible with index signature.
Type 'Headers' is not assignable to type 'Serializable'.
Type 'Headers' is not assignable to type '{ [key: string]: Serializable; [key: number]: Serializable; [key: symbol]: Serializable; }'.
Index signature for type 'string' is missing in type 'Headers'.```
This should be resolved in the next release via #9488
🤖 Hello there,
We just published version 2.10.0-pre.0 which involves this issue. If you'd like to take it for a test run please try it out and let us know what you think!
Thanks!
🤖 Hello there,
We just published version 2.10.0 which involves this issue. If you'd like to take it for a test run please try it out and let us know what you think!
Thanks!