---
type: errors
language: javascript
slug: cannot-convert-undefined-or-null
title: "TypeError: Cannot convert undefined or null to object"
title_tag: "Cannot convert undefined or null to object の直し方"
summary: >
  Object.keys() などに null や undefined を渡すと出ます。落ちるものと黙って通るものの違い、
  値がそこで null になった原因の追い方、落ちない受け取り方までを実行して確かめます。
description: >
  Object.keys は落ちるのに Object.assign は落ちません。この差が原因の切り分けを難しく
  します。落ちるものの一覧、?? {} で守る形、そもそもの出どころの追い方を示します。
status: published
difficulty: 2
minutes: 8

versions:
  verified: "Node 22.22.3"
  since: "ES5"
  deprecated: null
  removed: null

sources:
  - title: "Object.keys — ECMAScript® 2026 Language Specification"
    url: "https://tc39.es/ecma262/#sec-object.keys"
  - title: "ToObject — ECMAScript® 2026 Language Specification"
    url: "https://tc39.es/ecma262/#sec-toobject"
  - title: "TypeError: can't convert x to object — MDN"
    url: "https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Errors/Cant_convert_x_to_object"

terms: [ToObject, 列挙, 既定値]

links:
  related:
    - javascript/reference/object/keys
    - javascript/errors/cannot-read-properties-of-undefined
    - javascript/learn/object/iterate

content_updated_at: 2026-09-08
published_at: 2026-09-08
---

`Object.keys()` などに `null` か `undefined` を渡すと出ます。

```js bad
Object.keys(null);
```
```output
TypeError: Cannot convert undefined or null to object
```

**文言に `undefined or null` と両方書いてあります。** どちらなのかは分かりません。
まず[key:渡している値そのもの]を出してください。

## 落ちるものと落ちないもの

**ここが分かりにくいところです。** 同じ `Object` の関数でも違います。

```js run
for (const value of [null, undefined]) {
  for (const [name, run] of [
    ['Object.keys', () => Object.keys(value)],
    ['Object.entries', () => Object.entries(value)],
    ['Object.assign', () => Object.assign({}, value)],
  ]) {
    try {
      run();
      console.log(String(value), name, '-> 通る');
    } catch (error) {
      console.log(String(value), name, '->', error.name);
    }
  }
}
```
```output
null Object.keys -> TypeError
null Object.entries -> TypeError
null Object.assign -> 通る
undefined Object.keys -> TypeError
undefined Object.entries -> TypeError
undefined Object.assign -> 通る
```

`Object.assign()` は[bad:黙って無視します]。

```js run
console.log(Object.assign({}, null, { a: 1 }));
console.log({ ...null, ...undefined, a: 1 });
```
```output
{ a: 1 }
{ a: 1 }
```

**スプレッド構文も落ちません。**
だから「同じような書き方なのに、ここだけ落ちる」ことになります。

| 書き方 | `null` / `undefined` を渡すと |
|---|---|
| `Object.keys()` `values()` `entries()` | [bad:例外] |
| `Object.assign()` | 無視して通る |
| `{ ...value }` | 無視して通る |
| `Object.freeze()` | そのまま返る |

## 文字列や数値なら落ちない

```js run
console.log(Object.keys('ab'));
console.log(Object.keys(1));
console.log(Object.keys(true));
```
```output
[ '0', '1' ]
[]
[]
```

**落ちるのは `null` と `undefined` だけ**です。
ほかの値は、いったんオブジェクトとして扱われます。

文字列は[key:添字が鍵]になります。
[bad:意図せず文字列を渡していると、空でない配列が返って気づけません。]

## 原因の追い方

**「なぜそこが `null` なのか」が本体です。** 落ちた行ではなく、値の出どころを見ます。

```js run
function summarize(source) {
  console.log('受け取った値:', source);
  return Object.keys(source ?? {}).length;
}

console.log(summarize({ a: 1, b: 2 }));
console.log(summarize(null));
```
```output
受け取った値: { a: 1, b: 2 }
2
受け取った値: null
0
```

よくある出どころは次のとおりです。

| 出どころ | 起きること |
|---|---|
| 通信の応答 | 本文が空、または `null` が返っている |
| `JSON.parse('null')` | **例外にならず `null` が返る** |
| `find()` の結果 | 見つからないと `undefined` |
| `match()` の結果 | 見つからないと `null` |
| 分割代入の取りこぼし | 鍵が無いと `undefined` |

`JSON.parse('null')` は特に気づきにくい形です。
→ [SyntaxError: Unexpected end of JSON input](/ja/javascript/errors/unexpected-end-of-json/)

## 落ちない受け取り方

**`?? {}` を挟むのがいちばん短い**です。

```js run
function keysOf(value) {
  return Object.keys(value ?? {});
}

console.log(keysOf({ a: 1 }));
console.log(keysOf(null));
console.log(keysOf(undefined));
```
```output
[ 'a' ]
[]
[]
```

`||` ではなく `??` を使ってください。`||` は `0` や空文字も置き換えます。
→ [なぜ == ではなく === を使うのか](/ja/javascript/why/strict-equality/)

**ただし、隠していいのかを先に考えてください。**

```js run
function keysOf(value) {
  if (value == null) {
    throw new TypeError('データが取得できていません');
  }

  return Object.keys(value);
}

console.log(keysOf({ a: 1 }));

try {
  keysOf(null);
} catch (error) {
  console.log(error.name + ': ' + error.message);
}
```
```output
[ 'a' ]
TypeError: データが取得できていません
```

[em:「無くて当たり前」なら `?? {}`、「無いのはおかしい」なら早く落とす。]
`?? {}` を機械的に付けると、**本当の原因が空の一覧として現れます。**

## 一覧の途中に混ざっていると気づきにくい

```js bad
const rows = [{ a: 1 }, null, { b: 2 }];

rows.map((row) => Object.keys(row).length);
```
```output
TypeError: Cannot convert undefined or null to object
```

**3件のうち1件だけが `null`** です。1件目は通っているので、
「動くときと動かないときがある」ように見えます。

守るなら、要素ごとに受けます。

```js run
const rows = [{ a: 1 }, null, { b: 2 }];

console.log(rows.map((row) => Object.keys(row ?? {}).length));
```
```output
[ 1, 0, 1 ]
```

[em:件数が 0 で出てきたら、そこに `null` が混ざっていた合図です。]

## 空を渡したときに何が返るか

```js run
console.log(Object.entries(null ?? {}));
console.log(Object.keys([]));
console.log(Object.keys([10, 20]));
console.log(Object.keys(() => {}));
```
```output
[]
[]
[ '0', '1' ]
[]
```

配列を渡すと[key:添字が鍵]として返ります。関数は空です。
**「空が返った」だけでは、元が何だったかは分かりません。**

## 似ているエラーとの違い

| 文言 | 意味 |
|---|---|
| `Cannot convert undefined or null to object` | **`null` / `undefined` をオブジェクトとして扱おうとした** |
| `Cannot read properties of undefined` | `undefined` の[key:中身]を読もうとした |
| `x is not defined` | そもそも宣言が無い |
| `x is not a function` | 関数でないものを呼んだ |

前の2つは近く見えますが、**渡したのか読んだのか**が違います。

```js run
try {
  Object.keys(null);
} catch (error) {
  console.log('渡した:', error.name);
}

try {
  null.foo;
} catch (error) {
  console.log('読んだ:', error.message);
}
```
```output
渡した: TypeError
読んだ: Cannot read properties of null (reading 'foo')
```

[dim:このページの実行結果は Node 22.22.3 のものです。文言は処理系と版によって変わります。]

## 探しかたの順序

1. **渡している値をそのまま出す。** `null` か `undefined` かを確かめる
2. その値の**出どころ**まで遡る（通信・`find()`・`match()`・分割代入）
3. **無くて当たり前か**を決める
   - 当たり前 → `?? {}` で受ける
   - おかしい → その場で落として、原因が分かる文言を付ける

## まとめ

- 落ちるのは `Object.keys()` / `values()` / `entries()` など
- **`Object.assign()` とスプレッド構文は黙って無視する。** この差が切り分けを難しくする
- 文字列や数値では落ちない。**文字列は添字が鍵になる**
- 直すのは落ちた行ではなく、**値の出どころ**
- `?? {}` で受けるか、早く落とすかを[em:意図して選ぶ]
