TypeError: Cannot set properties of undefined (setting 'X')

Quick answer

You wrote obj.a.b = value, but obj.a is undefined — there's no object there to set .b on. This is the write-side version of Cannot read properties of undefined: every intermediate level in a nested write must already exist. Initialize the missing parent to {} (or []) before writing to it.

The exact error string

const result = {};
result.stats.count = 1;
// Uncaught TypeError: Cannot set properties of undefined (setting 'count')
//   -> result.stats is undefined, so there's nowhere to put "count"

Read vs write: why this one always throws

Reading result.stats when it doesn't exist just gives you undefined — you can keep going (and chain into a crash later, as in the "reading" version of this error). Writing has no such fallback: JavaScript needs a real object to attach the new property to, and if the parent is undefined, there's nowhere to put it, so it throws immediately at the assignment.

Cause 1: writing into a nested path that isn't built yet

const config = {};
config.server.port = 3000;
// ❌ config.server is undefined

const config = {};
config.server = config.server || {};   // ✅ initialize the parent first
config.server.port = 3000;

// or build the shape up front:
const config = { server: { port: 3000 } };   // ✅

Cause 2: grouping array items by a dynamic key

const groups = {};
for (const item of items) {
  groups[item.category].push(item);
  // ❌ groups[item.category] is undefined the first time this category appears
}

const groups = {};
for (const item of items) {
  groups[item.category] = groups[item.category] || [];   // ✅ initialize the bucket
  groups[item.category].push(item);
}

Cause 3: mutating nested React/Redux state directly

// ❌ direct mutation, and settings may not exist on the current state
state.user.settings.theme = "dark";

// ✅ build a new object, spreading each level you touch
setState(prev => ({
  ...prev,
  user: {
    ...prev.user,
    settings: { ...prev.user.settings, theme: "dark" },
  },
}));

Cause 4: a typo'd or wrong-cased intermediate key

const data = { userProfile: {} };
data.userprofile.name = "Ada";
// ❌ "userprofile" (lowercase p) doesn't exist — data.userProfile does

data.userProfile.name = "Ada";   // ✅ match the actual key exactly

Fix: nullish-assignment shortcut

Modern JavaScript's ??= operator initializes a value only if it's currently null/undefined, which is a compact way to guarantee the parent exists right before you write to it:

const config = {};
config.server ??= {};     // sets {} only if config.server is null/undefined
config.server.port = 3000;   // ✅ now safe

Common variants at a glance

PatternMissing parentFix
obj.a.b = xobj.aobj.a ??= {} before writing
groups[key].push(x)groups[key]initialize the bucket first
direct nested state mutationa state sub-objectrebuild with spreads, don't mutate
typo'd/mis-cased keythe wrong key entirelymatch the real property name

Debugging checklist

Frequently Asked Questions

What does 'Cannot set properties of undefined (setting X)' mean?

You tried to write obj.a.b = value, but obj.a itself is undefined — there is no object there to set a property on. This is the write-side counterpart of "Cannot read properties of undefined": the same missing-parent problem, encountered while assigning instead of reading.

Why does building up a nested object fail like this?

Writing to a nested path requires every intermediate level to already be an object — result.stats.count = 1 needs result.stats to exist first. Unlike reading (which just gives undefined and lets you continue), writing to a property of undefined throws immediately, because there is nowhere to store the value.

How do I initialize a nested object safely?

Check and create each missing level before writing the final value: if (!obj.a) obj.a = {}; then obj.a.b = value. Or build the whole structure with a single object literal up front if you know its shape ahead of time, rather than assigning into it level by level.

Why does this happen when grouping array items into an object?

A common reduce pattern groups[item.category].push(item) fails the first time a new category key is seen, because groups[item.category] is still undefined. Initialize the bucket first: groups[item.category] = groups[item.category] || []; then push.

Why does this happen with React state?

Directly mutating nested state — state.user.settings.theme = 'dark' — both violates React's immutability expectations and throws this error if settings doesn't exist yet on the current state object. Use setState with a new object (spreading each level) instead of writing into the existing state tree.

How do I fix this quickly?

Find the parent in the write path that is undefined (the message doesn't say which — trace the chain manually or log each level), initialize it to an empty object or array before the write, or use a library/utility (like lodash's set, or optional chaining with nullish assignment obj.a ??= {}) to create intermediate levels safely.

More JavaScript & runtime errors

Browse the full reference for JavaScript, Node.js, and database errors — exact message, cause, and fix.

All Error References Cannot read properties of undefined HTTP Status Codes
About the author

Pasindu Ishan is a software developer based in Sri Lanka. He builds privacy-first developer tools at JSON Dev Tools.