facebook/react · error · Error

438

438

Error message

An unsupported type was passed to use(): ${String(usable)}

What it means

Fizz's use() accepts only three shapes: a thenable (object with a .then function), an instrumented promise (object with a string status field), and a React context (REACT_CONTEXT_TYPE). Any other value — primitives, plain objects, arrays, functions without .then — falls through to the final branch and throws error code 438 with the coerced value in the message.

Source

Thrown at packages/react-server/src/ReactFizzHooks.js:839

    // $FlowFixMe[method-unbinding]
    if (typeof usable.then === 'function') {
      // This is a thenable.
      const thenable: Thenable<T> = usable as any;
      return unwrapThenable(thenable);
    } else if (usable.$$typeof === REACT_RECOVERABLE_TYPE) {
      // Create the recoverable error here so its stack captures the component
      // that passed this value to use(). The internal brand lets the renderer
      // distinguish it from an Error thrown by application code.
      const recoverable: ReactRecoverable = usable as any;
      throw createRecoverableError(recoverable);
    } else if (usable.$$typeof === REACT_CONTEXT_TYPE) {
      const context: ReactContext<T> = usable as any;
      return readContext(context);
    }
  }

  // eslint-disable-next-line react-internal/safe-string-coercion
  throw new Error('An unsupported type was passed to use(): ' + String(usable));
}

export function unwrapThenable<T>(thenable: Thenable<T>): T {
  const index = thenableIndexCounter;
  thenableIndexCounter += 1;
  if (thenableState === null) {
    thenableState = createThenableState();
  }
  return trackUsedThenable(thenableState, thenable, index);
}

export function readPreviousThenableFromState<T>(): T | void {
  const index = thenableIndexCounter;
  thenableIndexCounter += 1;
  if (thenableState === null) {
    return undefined;
  }
  return readPreviousThenable(thenableState, index);

View on GitHub (pinned to eafeac097b)

Solutions

  1. Pass only a Promise/thenable or a React context object to use()
  2. In an async Server Component, use plain await for values instead of use()
  3. If you meant to read context, pass the context object returned by createContext, not its current value

Example fix

// before
const settings = use({theme: 'dark'}); // plain object -> throws

// after
const settings = use(fetchSettings()); // a Promise/thenable
// or, inside an async Server Component:
const settings = await fetchSettings();
Defensive patterns

Strategy: type-guard

Validate before calling

if (!isUsable(value)) {
  throw new TypeError('use() expects a Promise, thenable, or Context');
}

Type guard

function isUsable(value) {
  if (value !== null && typeof value === 'object') {
    return (
      typeof value.then === 'function' ||
      typeof value.status === 'string' ||
      value.$$typeof === Symbol.for('react.context')
    );
  }
  return false;
}

Prevention

When it happens

Trigger: use({value: 1}), use(['a', 'b']), use(42), or use('text') inside a component during SSR; passing a context's current value instead of the context object; passing an object that mimics a promise but has no then method.

Common situations: Assuming use() works like await for arbitrary values; passing deserialized props or config objects directly to use(); a Promise polyfill or wrapper without .then.

Related errors


AI-assisted analysis of facebook/react@eafeac097b (2026-08-21). Data as JSON: /api/errors/f11b70c7bf29caf5. Report an issue: GitHub.