streamich/react-use · error · TypeError
Router route must be a string.
Error message
Router route must be a string.
What it means
Thrown by the Router component produced by createRouter when its `route` prop is not a string, but only when process.env.NODE_ENV !== 'production' (a dev-only invariant). RouterProviderProps types route as `string`, so in TypeScript this path is normally unreachable; the guard exists for JavaScript consumers or loosely-typed usage that passes a number, undefined, or object as route. Note: the current createRouter source does not actually return/export the Router component (no return statement in createRouter), so reaching this throw also implies the consumer wired it up manually.
Source
Thrown at src/factory/createRouter.ts:21
export interface RouterProviderProps {
route: string;
fullRoute?: string;
parent?: any;
}
const createRouter = () => {
const context = React.createContext<RouterProviderProps>({
route: '',
});
// not sure if this supposed to be unused, ignoring ts error for now
// @ts-ignore
const Router: React.SFC<RouterProviderProps> = (props) => {
const { route, fullRoute, parent, children } = props;
if (process.env.NODE_ENV !== 'production') {
if (typeof route !== 'string') {
throw new TypeError('Router route must be a string.');
}
}
return React.createElement(context.Provider as any, {
value: {
fullRoute: fullRoute || route,
route,
parent,
},
children,
});
};
};
export default createRouter;
View on GitHub (pinned to fbe99c6327)
Solutions
- Ensure the route prop is always a string: <Router route={String(route)}/> or guard with a default <Router route={route ?? ''}/>.
- Fix the upstream value so it is a string path before it reaches Router (e.g. resolve the URL/path from your state/routing lib).
- If the value can be undefined during loading, defer rendering Router until the route is known, or pass a placeholder empty string.
- Confirm you are consuming the component returned by createRouter correctly (the factory must return the Router/Provider; verify exports).
Example fix
// before
<Router route={maybeUndefinedRoute}/>
<Router route={locationObject}/>
// after
<Router route={route ?? ''}/>
<Router route={locationObject.pathname}/> Defensive patterns
Strategy: validation
Validate before calling
function renderRouter(route: unknown) {
if (typeof route !== 'string') {
throw new TypeError(`Expected route to be a string, got ${typeof route}`);
}
return <Router route={route}/>;
}
// or default before rendering:
const safeRoute = typeof route === 'string' ? route : '';
return <Router route={safeRoute}/>; Type guard
const isRouteString = (v: unknown): v is string => typeof v === 'string';
if (isRouteString(route)) {
return <Router route={route}/>;
}
// handle the non-string case (loading / error) Try / catch
// The throw happens during render in dev; catch it with an error boundary
// while you fix the upstream value.
class RouteBoundary extends React.Component<
{ children: React.ReactNode; fallback: React.ReactNode },
{ hasError: boolean }
> {
state = { hasError: false };
static getDerivedStateFromError() { return { hasError: true }; }
componentDidCatch(e: unknown) { console.warn('Router route invalid:', e); }
render() { return this.state.hasError ? this.props.fallback : this.props.children; }
} Prevention
- Type route as string at the source and let TypeScript reject non-string values.
- Coerce or default optional route values (route ?? '') before passing them in.
- Defer rendering Router until the route has resolved to a known string.
- Remember this guard is dev-only (NODE_ENV !== 'production'); do not rely on it as a runtime contract in production builds.
When it happens
Trigger: Rendering <Router route={someValue}/> where someValue is not a string (e.g. a number, undefined, null, or object) while running outside production mode. Commonly happens when route is computed and can be undefined before data loads, or when a non-string value (like a route object or index) is forwarded into the prop.
Common situations: Passing an uninitialized/optional route that resolves to undefined before async data settles; forwarding a numeric id or a parsed location object instead of the path string; JS consumers bypassing the TS `route: string` type; conditional spreads like {...(cond && {route: value})} that omit route entirely (undefined).
Related errors
- states expected to be an object or array, got ${typeof state
- useReducerContext must be used inside a ReducerProvider.
- useStateContext must be used inside a StateProvider.
- useLocalStorage key may not be falsy
- State '${state}' is not a valid state (does not exist in sta
AI-assisted analysis of streamich/react-use@fbe99c6327 (2026-08-12).
Data as JSON: /api/errors/f8dc11ff7a077d51.
Report an issue: GitHub.