remix-run/react-router · error

No value found for context

Error message

No value found for context

What it means

RouterContextProvider.get(context) (lib/router/utils.ts:250) throws when no value was ever set for that context and it was created without a defaultValue. The intended flow is: a middleware on a parent route calls context.set() early, and loaders/actions below it call context.get(); reading before any setter ran is treated as a wiring bug.

Solutions

  1. Give the context a default: createContext<User | null>(null) so get() returns it instead of throwing
  2. Ensure the middleware that sets the value is defined on a parent route of every route that reads it
  3. Set the value unconditionally in middleware (fallback value) before any branch that skips it
  4. Check route nesting: the reading route must be nested under the middleware route

Example fix

// before
export const userContext = createContext<User>()
// after
export const userContext = createContext<User | null>(null)
Defensive patterns

Strategy: validation

Validate before calling

// Defensive read: provide defaults at creation so get() never throws
export const userContext = createContext<User | null>(null);
// and ensure a value is always set before readers run
export const userMiddleware = async ({ context, request }) => {
  context.set(userContext, (await getUser(request)) ?? null);
};

Try / catch

let user: User | undefined;
try { user = context.get(userContext) } catch (e) { if (e instanceof Error && e.message === 'No value found for context') user = undefined; else throw e }

Prevention

When it happens

Trigger: context.get(myContext) in a loader whose middleware never ran (middleware defined on a different branch or a child of the reading route); forgot the context.set() call in the middleware; middleware ordering puts the reader above the setter in the route tree; reading in getContext() before middleware ran.

Common situations: Adding context reads to new routes while the middleware only matches sibling branches; refactoring moves middleware to a different route; conditional set inside middleware skipped on some paths.

Related errors


AI-assisted analysis of remix-run/react-router@7aea711dd1 (2026-08-18). Data as JSON: /api/errors/88ac77066a3db095. Report an issue: GitHub.

Appendix: 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 7aea711dd1)