remix-run/react-router · error · Error
No value found for context
Error message
No value found for context
What it means
`RouterContextProvider.get(context)` throws when no value has been set for the requested `RouterContext` AND the context has no `defaultValue`. The provider stores values in a private map; on miss it falls back to `context.defaultValue`, and only throws if that is also undefined.
Source
Thrown at packages/react-router/lib/router/utils.ts:250
/**
* Access a value from the context. If no value has been set for the context,
* it will return the context's `defaultValue` if provided, or throw an error
* if no `defaultValue` was set.
* @param context The context to get the value for
* @returns The value for the context, or the context's `defaultValue` if no
* value was set
*/
get<T>(context: RouterContext<T>): T {
if (this.#map.has(context)) {
return this.#map.get(context) as T;
}
if (context.defaultValue !== undefined) {
return context.defaultValue;
}
throw new Error("No value found for context");
}
/**
* Set a value for the context. If the context already has a value set, this
* will overwrite it.
*
* @param context The context to set the value for
* @param value The value to set for the context
* @returns {void}
*/
set<C extends RouterContext>(
context: C,
value: C extends RouterContext<infer T> ? T : never,
): void {
this.#map.set(context, value);
}
}
View on GitHub (pinned to 1fd704a7da)
Solutions
- Ensure an upstream middleware (or `getLoadContext`) calls `context.set(MyContext, value)` before any downstream code calls `get(MyContext)`.
- Create the `RouterContext` with a `defaultValue` so reads never throw.
- Confirm all readers reference the exact same `RouterContext` instance the writer used (module identity).
Example fix
// before
const Ctx = createRouterContext<string>(); // no default
// in a loader:
context.get(Ctx); // throws
// after (option A: default)
const Ctx = createRouterContext<string>('guest');
// after (option B: set upstream)
export const middleware = async ({ context }, next) => {
context.set(Ctx, 'user-123');
return next();
}; Defensive patterns
Strategy: validation
Validate before calling
function hasContextValue<T>(p: RouterContextProvider, c: RouterContext<T>): boolean {
try { p.get(c); return true; } catch { return false; }
}
if (!hasContextValue(context, MyContext)) context.set(MyContext, defaultValue); Type guard
function tryGetContext<T>(p: RouterContextProvider, c: RouterContext<T>): T | undefined {
try { return p.get(c); } catch { return undefined; }
} Try / catch
let value: T;
try {
value = context.get(MyContext);
} catch {
value = fallbackValue;
} Prevention
- Create contexts with a `defaultValue` when a fallback is acceptable.
- Set context in the topmost middleware before any reader runs.
- Import the same `RouterContext` instance from a single module.
When it happens
Trigger: Calling `context.get(SomeContext)` from a loader/action/middleware for a context that was never set by an upstream middleware or by the server's getLoadContext, and whose `RouterContext` was created without a default.
Common situations: Forgetting to declare/set a shared context in a root middleware before a child route reads it; rename or refactor that changes the context object identity so `get` no longer finds the set value; reading context before the provider has been populated in the request lifecycle.
Related errors
- You may only call `next()` once per middleware
- A history only accepts one active listener
- You cannot call `runClientMiddleware()` from a static handle
- Cannot call `runClientMiddleware()` from within an `runClien
AI-assisted analysis of remix-run/react-router@1fd704a7da (2026-08-12).
Data as JSON: /api/errors/88ac77066a3db095.
Report an issue: GitHub.