Cannot read properties of undefined

The code asked for a property of a value that doesn’t exist yet, usually data that hasn’t loaded or a field the API didn’t return.

Browser console
TypeError: Cannot read properties of undefined (reading 'map')

Also appears as

  • TypeError: Cannot read properties of null (reading 'addEventListener')
  • TypeError: undefined is not an object (evaluating 'data.map')
  • TypeError: null is not an object (evaluating 'button.addEventListener')
  • TypeError: can't access property "map", data is undefined
  • TypeError: Cannot read property 'map' of undefined

Prompt to fix it

My app crashes with "TypeError: Cannot read properties of undefined (reading 'map')" (or of null). Find the line and figure out which value is undefined or null and why: data that hasn’t loaded yet, an API or Supabase response with a different shape, a query that matched no row, or a DOM element that doesn’t exist yet. Fix the cause: give state a correct initial value, add loading, empty, and error states, and match the code to the real response shape. Use optional chaining only where a missing value is expected, and don’t add it everywhere just to stop the crash.

Paste into Layerwise or any AI coding tool.

What it means

In data.map(...), JavaScript first looks up data, then looks for map on it. If data is undefined or null, there is nothing to look in, so it throws. The word in parentheses, (reading 'map'), is the property it wanted. The value just before that property in your code is the one that’s missing.

In React apps this usually happens on the first render. The component renders before the fetch finishes, so state that will hold a list is still undefined, or the response puts the list under a different key than the code expects. The null form often comes from a lookup that found nothing, such as document.querySelector or a database query with no matching row.

Optional chaining, as in data?.map(...), stops the crash. If the value should always exist, it also hides the real bug and leaves a blank screen. Give state a real starting value, show a loading state, and check what the API actually returns.

Common causes

  • State starts as undefined or null, and the component reads from it before the data loads.
  • The API or database returned a different shape than the code expects, such as a list nested under items or an error object.
  • A Supabase query with .single() or .maybeSingle() returned null for data because no row matched.
  • A DOM lookup like document.querySelector('#menu') returned null because the element isn’t on the page yet.

How to fix it

  1. Click the error in the console to open the failing line, and find the value right before the property named in (reading '...').
  2. Log that value, or open the request in the Network tab, to see what actually came back.
  3. Give state the shape it will have: useState<Todo[]>([]) for lists, or null plus a loading check for a single record.
  4. Render a loading or empty state until the data exists, and handle the error and no-row cases from your API or Supabase call.
  5. Use ?. or ?? only where a missing value is expected and harmless, such as an optional field.

Example fix

import { useEffect, useState } from 'react';

type Todo = { id: string; title: string };

export function TodoList() {
  // An empty array is safe to .map() before the data arrives.
  const [todos, setTodos] = useState<Todo[]>([]);

  useEffect(() => {
    fetch('/api/todos')
      .then((res) => res.json())
      .then((body: { todos?: Todo[] }) => setTodos(body.todos ?? []));
  }, []);

  return (
    <ul>
      {todos.map((todo) => (
        <li key={todo.id}>{todo.title}</li>
      ))}
    </ul>
  );
}
All errors
TypeError: data.map is not a function

X is not a function

The code called something that isn’t a function, most often .map on API data that came back as an object or a string instead of an array.

Cannot coerce the result to a single JSON object

Cannot coerce the result to a single JSON object

A Supabase query asked for exactly one row with single(), but its filter matched no rows or more than one.

Objects are not valid as a React child (found: object with keys {id, title}). If you meant to render a collection of children, use an array instead.

Objects are not valid as a React child

React was asked to show a whole object, such as a database row or a date, on the page, and it can only show text, numbers, and elements.

ReferenceError: useState is not defined

X is not defined

The code used a name JavaScript can’t find anywhere, usually because of a missing import, a typo, or a Node-only global like process in the browser.

Build with an agent that checks its work

The Layerwise agent clicks through the live preview and reads the console, so it catches errors before you do.