TypeError: Cannot convert undefined or null to object

Object.keys() などに null や undefined を渡すと出ます。落ちるものと黙って通るものの違い、値がそこで null になった原因の追い方、落ちない受け取り方までを実行して確かめます。

実行して検証済み処理系Node 22.22.3対応ES5難易度●●○○○目安8更新

Object.keys() などに nullundefined を渡すと出ます。

javascript
Object.keys(null);
TypeError: Cannot convert undefined or null to object
example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
null Object.keys -> TypeError null Object.entries -> TypeError null Object.assign -> 通る undefined Object.keys -> TypeError undefined Object.entries -> TypeError undefined Object.assign -> 通る

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

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

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

example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
{ a: 1 } { a: 1 }
example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
[ '0', '1' ] [] []

Object.assign()黙って無視します

example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
受け取った値: { a: 1, b: 2 } 2 受け取った値: null 0
example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
[ 'a' ] [] []

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

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

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

example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
[ 'a' ] TypeError: データが取得できていません
javascript
const rows = [{ a: 1 }, null, { b: 2 }];

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

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

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

原因の追い方

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

example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
[ 1, 0, 1 ]
example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
[] [] [ '0', '1' ] []

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

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

JSON.parse('null') は特に気づきにくい形です。 → SyntaxError: Unexpected end of JSON input

落ちない受け取り方

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

example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
渡した: TypeError 読んだ: Cannot read properties of null (reading 'foo')

|| ではなく ?? を使ってください。||0 や空文字も置き換えます。 → なぜ == ではなく === を使うのか

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

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

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

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

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

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

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

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

似ているエラーとの違い

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

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

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

探しかたの順序

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

まとめ

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

この記事の根拠

  1. Object.keys — ECMAScript® 2026 Language Specificationtc39.es
  2. ToObject — ECMAScript® 2026 Language Specificationtc39.es
  3. TypeError: can't convert x to object — MDNdeveloper.mozilla.org

掲載しているコード例は、公開前に読み手が押したときに動くのと同じもので実行して出力を突き合わせています。結果はリポジトリに残しています。

このページの原文(Markdown)