All posts
javascripttypeerror

Fixing "Cannot convert undefined or null to object" in JavaScript

Why JavaScript throws Cannot convert undefined or null to object, which built-in methods trigger it, and how to fix each case.

SR

Suhail Roushan

August 6, 2026

·
5 min read
·
0 views

TypeError: Cannot convert undefined or null to object happens when a specific set of JavaScript's built-in object methods — Object.keys(), Object.values(), Object.entries(), and a few others — receive null or undefined instead of an actual object, since these methods explicitly reject those two values rather than silently returning an empty result.

This error means you called one of a specific set of Object static methods with null or undefined as the argument — unlike accessing a property on null/undefined (which throws a different, more common error), these particular methods have their own explicit check that produces this specific message.

Why This Error Happens

Object.keys(), Object.values(), Object.entries(), Object.assign() (as a target), and similar methods perform an internal ToObject conversion on their argument — and the ECMAScript specification explicitly defines this conversion as throwing for null and undefined specifically, unlike most other values which get coerced into an object wrapper. This most commonly surfaces when the value being passed is the result of an API call, a database query, or optional data that turned out to be missing.

Reproducing the Error

A common case — calling Object.keys() on data that might not have loaded yet:

async function getUserSettings(userId: string) {
  const response = await fetch(`/api/users/${userId}/settings`);
  if (response.status === 404) return undefined; // no settings found

  const settings = await response.json();
  return settings;
}

const settings = await getUserSettings("123");
const keys = Object.keys(settings);
// throws: Cannot convert undefined or null to object, if settings is undefined

Core Concepts Behind This Error

This is a distinct error from accessing a property on null/undefined (Cannot read properties of undefined) — that happens with property access (obj.foo); this one happens specifically with the small set of Object static methods performing their internal object conversion, which is worth distinguishing since the fix locations differ (the call site of these specific methods, not general property access).

Optional or not-yet-loaded data is the most common real-world trigger — API responses that can legitimately return no data, database queries that can return null for a missing record, or component state that starts as undefined before an async load completes, all commonly flow into a later Object.keys()/Object.values()/Object.entries() call without an intermediate check.

Default parameter values and nullish coalescing are effective preventive patterns here specifically because these methods have well-defined, harmless behavior on an empty objectObject.keys({}) returns [], so substituting an empty object for a potentially-null value produces the same practical result as the object genuinely having no keys, without needing branching logic at every call site.

Destructuring, spreading, and these Object methods all share this same underlying null/undefined sensitivity{ ...maybeNull } doesn't throw (spread silently treats null/undefined as contributing nothing) but Object.keys(maybeNull) does throw, which is a specification inconsistency worth being aware of since the two look similar but behave differently on the same missing input.

Fixing "Cannot Convert Undefined or Null to Object"

Fix 1: Provide a default empty object at the source, using nullish coalescing:

const settings = (await getUserSettings("123")) ?? {};
const keys = Object.keys(settings); // safe, returns [] if settings was missing

Fix 2: Guard explicitly before calling the method, when the missing case needs distinct handling rather than being treated as equivalent to empty:

const settings = await getUserSettings("123");
if (!settings) {
  return renderEmptyState();
}
const keys = Object.keys(settings);

Fix 3: Fix the function's return contract to never return null/undefined for this kind of data, returning an empty object as the "no data" representation from the source itself, which prevents every downstream consumer from needing its own guard:

async function getUserSettings(userId: string): Promise<Record<string, unknown>> {
  const response = await fetch(`/api/users/${userId}/settings`);
  if (response.status === 404) return {}; // consistent empty-object contract
  return response.json();
}

Should You Fix This at the Source or at Every Call Site?

Fix it at the source (the function's return contract) when the "no data" case is genuinely equivalent to "empty object" for every consumer — this avoids needing a guard everywhere the value is used. Fix it at individual call sites when different consumers need to treat "missing" differently from "empty" (one caller shows an error state, another treats it as empty) — collapsing that distinction at the source would lose information some callers actually need.

Preventing This Error in Production

Establish a consistent contract for functions that can return "no data" — prefer returning an empty object/array over null/undefined when callers would otherwise need to guard before using Object methods, unless the missing/empty distinction is genuinely meaningful to callers. Use TypeScript's strict null checks to catch potential null/undefined values flowing into these methods at compile time, rather than discovering the gap through a runtime error.

If you hit this error, trace back to where the value originated and decide whether "missing" should really be represented as null/undefined at all — often, returning an empty object from the source is simpler and safer than guarding every downstream consumer individually.

Related posts

Written by Suhail Roushan — Full-stack developer. More posts on AI, Next.js, and building products at suhailroushan.com/blog.

Get in touch