ホーム·エラーメッセージ

エラーメッセージの読み方事典

104件のエラーメッセージを、意味・原因・対処の順で解きました。

直す命令には代償があります。git reset --hard はコミットしていない作業を捨て、強制プッシュは他人のコミットを消し、docker system prune は名前のないボリュームを削除します。該当する箇所には、その代償を書いてあります。

Git29

git のエラーはほぼすべて「その状態でそれをやると何かが失われる」という拒否であり、fatal: は何も変えずに止まったという意味なので、一行目より下の hint: 行に本当の解決策が書かれていることが多いです。

fatal: refusing to merge unrelated histories合わせようとしている二つの側が共通の祖先を一つも持っていない、つまり git から見れば互いに無関係な二つの歴史だという意味です。手元で git init から始めていくつかコミットし、その後すでにコミットのあるリモートを origin に足して pull したときに出ます。--allow-unrelated-histories を付ければ合わせられますが、無関係な二つの歴史が一つのコミットで無理に結ばれ、後から切り分けるのは困難です。手元のコミットが数個なら、リモートを新しく clone してファイルだけ移すほうがきれいです。Your branch and 'origin/main' have diverged自分のブランチと origin/main が、互いに持っていないコミットをそれぞれ抱えている、つまり歴史が二本に分かれたという意味です。手元でコミットしている間に誰かがリモートへ push した場合や、すでに push したコミットを amend や rebase で書き換えた場合に起きます。git pull --rebase は自分のコミットを相手の上に載せ直して歴史を一本にしますが、コミットのハッシュが新しくなるため、そのコミットをすでに他人と共有していたら同じ作業が二度残ります。その場合はマージコミットを一つ残す --no-rebase のほうが安全です。fatal: Need to specify how to reconcile divergent branches.git 2.34 以降、pull は歴史が分かれているときにマージか rebase かを自分で決めず止まります。壊れたのではなく、設定を尋ねているだけです。歴史が分かれている状態で pull.rebase を一度も決めていないと出ます。pull.ff only は早送りできるときだけ取り込み、できなければ何も作らずに止まるので最も安全で、pull.rebase true は毎回手元のコミットのハッシュを書き換え、false はマージコミットを残します。CONFLICT (content): Merge conflict in src/app.tsx両方の側が同じ行を別々に書き換えたため、git はどちらが正しいか決められないという意味です。git はそのファイルの中に <<<<<<<、=======、>>>>>>> の印で二つの版を並べて書き込み、止まっています。自分と誰かが同じ箇所を触ったときや、その箇所を直したコミットを越えて rebase したときに起きます。ファイルを開いて正しい形に直し、印を消してから git add して commit すれば終わります。git merge --abort はマージ前の状態にそのまま戻せますが、手で解決した分は一緒に消えます。コミット済みのものは残ります。Please commit your changes or stash them before you merge.取り込むコミットが触るファイルに、まだコミットしていない変更が残っているため、git は上書きするより止まることを選んだという意味です。作業中のファイルをそのままにして pull や merge をすると出ます。git stash push -u はその変更をいったん脇へ置いてマージを通し、-u で未追跡のファイルも一緒に含めます。ただし git stash pop で戻すときに同じ箇所で衝突し得るうえ、stash はブランチのように目に見えず忘れて失いやすいので、使い捨てのコミットを一つ作るほうが安全です。error: Your local changes to the following files would be overwritten by checkout:別のブランチへ移ろうとしているが、そちらで内容が違うファイルにまだコミットしていない変更が残っているという意味です。作業を途中まで進めたまま switch や checkout をすると出ます。git stash push -u で脇へ置くか使い捨てのコミットを作れば移れて、後で戻せます。検索でよく出てくる git checkout --force や git switch --discard-changes は確かに移してくれますが、コミットしていないその変更を永久に消します。reflog にも残らないので取り戻す手はありません。You are currently rebasing branch 'feature' on '8a3f21c'.rebase が始まって途中で止まっており、HEAD がブランチではなく作業用の一時的な状態に置かれているという意味です。rebase 中に衝突したときや、git rebase -i の edit・break で止まったのに終わらせず別の作業をしたときに、この行を見ます。衝突を直して git add し、git rebase --continue で続けるか、そのコミットを捨てるつもりなら --skip を使います。git rebase --abort は rebase を始める前の位置へ正確に戻すので、コミット済みのものは何も失いませんが、ここまで手で解決した分は一緒に消えます。You are in 'detached HEAD' state.HEAD がブランチ名ではなくコミットそのものを指しているという意味です。ここで新しくコミットしても、そのコミットに名前は付きません。コミットハッシュやタグを checkout したとき、サブモジュールの中にいるとき、CI が特定のコミットを checkout したときにこの状態になります。ここでの作業を残すなら git switch -c 名前 でブランチを作れば何も失いません。そのまま git switch main で出ると、ここで作ったコミットを指すものが無くなり、しばらくは reflog で拾えるだけで、gc が走れば消えます。Warning: you are leaving 1 commit behind, not connected to any of your branches:detached HEAD の状態でコミットし、いまその場を離れようとしているが、そのコミットを指すブランチが一つも無いという警告です。コミットハッシュを checkout して作業しコミットしたあと、元のブランチへ戻るときに出ます。メッセージに一緒に出ているハッシュをそのまま使い、git branch rescue 8a3f21c とすれば名前が付いて安全になります。この命令は他に何も変えず、名前を一つ足すだけです。すでに離れてしまっても git reflog には残っていますが、指すものが無いコミットは gc が走ると消えます — 既定でおよそ三十日です。error: failed to push some refs to 'https://github.com/user/repo.git'サーバーが push を拒否し、この行は結果の要約にすぎないという意味です。本当の理由はすぐ上の ! [rejected] の行に書かれています。多くはリモートに自分の持っていないコミットがあるためですが、保護されたブランチやサーバー側のフック、ファイルサイズ制限でも同じ要約が出ます。まず上の理由を読み、ふつうの場合は git pull --rebase && git push で終わります。理由を読まずに --force を付けるのが最も危険で、それはサーバーにある他人のコミットを消し得ます。! [rejected] main -> main (fetch first)リモートのブランチに、自分のクローンが一度も見たことのないコミットがあるため、いま push すると早送りにならないという意味です。同僚が先に push した場合や、最後の fetch から時間が経っている場合に出ます。git pull --rebase origin main でそのコミットを取り込み、自分の分をその上に載せ直せば push は通ります。ここで --force は決して使いません。上書きされるコミットは他人のもので、自分の手元には存在しないため、ローカルの何をもってしても取り戻せません。! [rejected] main -> main (non-fast-forward)自分のブランチがリモートのブランチの子孫になっていない、つまりそのまま押し込むとサーバー上のコミットが歴史から外れるという意味です。すでに push したコミットを rebase や amend、reset で書き換えたときに起きます。書き換えが意図的で、そのブランチを自分だけが使っているなら git push --force-with-lease を使います。これは最後の fetch 以降にリモートが動いていれば拒否するので、素の --force と違って、その間に入った同僚の push を黙って消すことはありません。意図していなかったなら、答えは force ではなく pull --rebase です。Updates were rejected because the remote contains work that you do not have locally.push が拒否された理由をかみくだいた案内です。リモートに自分のクローンが持っていない作業が入っており、いま押し込めばそれが失われるという意味です。同じブランチを複数人で使っている場合や、ウェブ上でファイルを直してコミットしたものをまだ取り込んでいない場合に出ます。git pull --rebase origin main で先に取り込んでから push すればそのまま通ります。この案内を無視して --force を付けるのは、案内が防ごうとしていたことそのものです。サーバーから他人のコミットが消え、その人が push した後に誰も fetch していなければ、どこにも残りません。error: src refspec main does not match anypush すると指定した名前が、手元にブランチとしてもタグとしても存在しないという意味です。無いものは送れません。作りたてでコミットが一つも無く main という名前がまだ生まれていない場合、ローカルのブランチが master なのに main と打った場合、あるいは単なる打ち間違いのときに出ます。git push -u origin HEAD はいま立っているブランチをその実際の名前で送るので、名前の食い違いは一手で片付きます。コミットがまだ無ければ、まず一つ作る必要があります。空のリポジトリには送るものがありません。fatal: The current branch feature has no upstream branch.このブランチに対応するリモートのブランチが記録されていないため、引数なしの git push や git pull がどこへ行けばよいか分からないという意味です。git switch -c でブランチを作り、一度も送っていないときに出ます。git push --set-upstream origin feature はサーバー側にそのブランチを作り、対応を一度だけ記録するので、以後は git push だけで済みます。この命令はローカル設定一行とサーバーの新しいブランチ一つを残すだけで、何も消さず、何度実行しても安全です。error: cannot lock ref 'refs/remotes/origin/main': is at 8a3f21c but expected 1c2d3e4git がリモート追跡参照に新しい値を書こうとした瞬間、その参照にはさっき読んだのとは違う値が入っていたため、上書きを拒んだという意味です。エディタが裏で自動的に fetch している間に自分も fetch した場合や、相手が force push してリモート追跡参照がずれている場合によく出ます。多くは fetch をもう一度実行すればそのまま通ります。git remote prune origin はサーバー側で消えたブランチのリモート追跡参照を片付けますが、消すのは自分のリポジトリ内の写しだけで、サーバーのブランチには触れません。fatal: not a git repository (or any of the parent directories): .gitいまのディレクトリにも、その上のどの親ディレクトリにも .git が無い、つまり git がリポジトリを見つけられなかったという意味です。リポジトリより一段上や下に立っている場合、clone が別のフォルダに入った場合、git init をまだしていない場合に出ます。まず pwd で自分の居場所を確かめ、本当にここでリポジトリを始めるつもりのときだけ git init を使います。既存リポジトリの下のフォルダで git init をすると内側に二つ目のリポジトリができて外側を黙って覆い、それ以降そのフォルダのファイルは外側のコミットに入りません。fatal: remote origin already exists.このリポジトリでは origin という名前がすでに使われており、同じ名前をもう一つ作れないという意味です。clone したリポジトリには最初から origin があり、その中で新規リポジトリ向けの手引きをそのまま辿って git remote add origin と打つと出ます。まず git remote -v で origin がどこを指しているか見て、アドレスを変えたかっただけなら git remote set-url origin で指す先だけ直します。この設定は .git/config の一行なのでいつでも戻せ、コミットには影響しません。error: pathspec 'featue' did not match any file(s) known to gitその名前のファイルもブランチもタグも git は見つけられなかったという意味です。引用符の中の文字列が、git が実際に探した名前そのものです。打ち間違い、そのブランチがサーバーにだけあって fetch していない、ファイルが思っていたのと違うディレクトリにある、といったときに出ます。ブランチなら git fetch のあと git branch -a で名前を目で照らし合わせ、ファイルなら git status --short で実際の経路を見ます。git の命令の経路はリポジトリの根ではなく、いま立っているディレクトリを基準に読まれるので、それだけで食い違うことも多いです。git@github.com: Permission denied (publickey).ssh はサーバーまで届いたが、サーバーが受け入れる鍵を一つも差し出せなかったという意味です。ネットワークの問題ではなく認証の問題です。鍵をまだ作っていない、作ったが ssh-agent に載せていない、公開鍵をそのサービスのアカウントに登録していない、といったときに出ます。ssh-add ~/.ssh/id_ed25519 で今回のセッションのあいだ鍵を agent に載せ、ssh -T git@github.com でどの鍵が試され誰として認識されるかを確かめます。どちらも読むだけなので失うものはありません。remote: Support for password authentication was removed on August 13, 2021.GitHub が 2021 年に https でのアカウントパスワード受け付けを止めたという意味です。パスワードが違うのではなく、パスワードという方式そのものがもう受け付けられません。保存された資格情報が古いパスワードのままの場合や、プロンプトにパスワードを入力した場合に出ます。https を続けるならパスワード欄に personal access token を入れ、そうでなければ git remote set-url origin で ssh のアドレスに変えます。リモートアドレスの変更は自分のクローンの設定一行なので、コミットには触れず、いつでも戻せます。fatal: Authentication failed for 'https://github.com/user/repo.git/'送った資格情報が拒否されたという意味です。間違っている、期限が切れている、あるいはそのリポジトリに必要な権限のないトークンです。よくある落とし穴は、期限切れのトークンが資格情報ヘルパーに残っている場合で、尋ねられることもなくそれが送られ、毎回同じ行が出ます。fix にある git credential reject の一行は保存されたその項目だけを消して次回また尋ねさせるので、新しいトークンを貼り付けられます。消すのは保存された資格情報だけで、リポジトリのデータには一切触れません。fatal: Unable to create '/repo/.git/index.lock': File exists.git は索引を書くあいだ .git/index.lock を錠として作るので、そのファイルが既にあるのは、別の git が動いているか、さきほど死んで置き去りにしたという意味です。エディタや IDE が裏で git を動かしているとき、あるいは命令を Ctrl+C や強制終了で断ち切ったときに残ります。動いている git が無いことを確かめてから rm -f .git/index.lock で消します。本当に働いている git があるのに消すと索引が壊れ得るので先に確認し、索引が狂ったら git reset で HEAD から作り直せます。--hard を付けなければファイルはそのままです。nothing to commit, working tree cleanこれはエラーではなく、直前のコミットと違うものが一つも無いと git が言っているだけです。コミットするものが無いので何もしていません。直したファイルが .gitignore に引っかかっているとき、編集した場所がいま立っているクローンやワークツリーと別のところだったとき、すでにコミットしたのを忘れていたときにこの行を見ます。git check-ignore -v パス はそのファイルを隠している .gitignore の行そのものを表示し、git log -1 でその変更がすでに入っているか確かめられます。どちらも読むだけの命令です。error: unable to unlink old 'dist/main.js': Permission deniedcheckout がファイルを新しい版に差し替えようとしたのに、OS が古いファイルの削除を許さなかったという意味です。別のプログラムがそのファイルを開いたままのとき(Windows で特に多い)、あるいはそのディレクトリに書き込み権限が無いときに出ます。そのファイルを掴んでいるもの — 開発サーバー、エディタ、ウイルス対策 — を閉じて同じ命令をもう一度実行し、Unix ならディレクトリの権限を直します。同じ命令の繰り返しは安全ですが、git が途中で止まっているため、成功するまで作業ディレクトリは半分だけ更新された状態で残ります。fatal: bad object 8a3f21c渡した名前が git の読めるものに解決されないという意味です。その物体がこのリポジトリに無いか、あっても壊れています。別のクローンや shallow clone から写してきたハッシュ、切れて桁数の足りないハッシュ、あるいはディスク障害の後に本当に壊れた物体のときに出ます。git fsck --full は欠けた物体や壊れた物体を読むだけで報告し、他人からもらったハッシュはまず git fetch をしないとその物体は入ってきません。fsck が破損を報告したら直そうとせず、もう一度 clone するほうが速く確実です。コミットしていないファイルだけ先に安全な場所へ写しておけば済みます。warning: LF will be replaced by CRLF in package.json.エラーではなく知らせです。core.autocrlf が入っているため、コミットには LF で収めるが作業ディレクトリの写しには CRLF を書き込む、という意味です。Windows で git を既定のまま入れると autocrlf が true になるので、その機械では add するたびに出ます。git config core.autocrlf input にすればコミットには LF で収め、取り出すときは変換しません。より良いのはリポジトリに .gitattributes を置いて * text=auto eol=lf と書き、どのクローンでも同じ挙動にすることです。設定を変えると全ファイルが一度だけ変更済みに見えることがありますが、これは一度取り出し直せば済む話で、作業が消えるわけではありません。The file will have its original line endings in your working directory先の CRLF の知らせと対になる後ろの行で、ディスク上のファイルはいま持っている行末をそのまま保ち、コミットに入る写しだけが正規化されるという意味です。同じ autocrlf 設定から出ているので、それ自体で壊れているものはありません。ただし diff にファイル全体が変わったように見えるなら、人によって行末が違う印なので、リポジトリに .gitattributes を一つ置いて規則を固定し、git add --renormalize . を一度実行します。この命令は行末の収め方だけを書き直し、ファイルの内容は変えません。husky - pre-commit hook exited with code 1 (error)コミットは作られなかったという意味です。lint やテスト、整形などのフックが 0 以外で終わり、git が中断しました。本当の理由はこの行ではなく、その上にあるフック自身の出力にあり、多くは lint 規則か型エラーです。フックが指摘したものを直してもう一度コミットするのが唯一の正解です。git commit --no-verify はコミットのフックを全部飛ばしてコミットを作りますが、検査を通したのではなく CI に先送りしただけで、整形されていないコードがそのまま同僚へ渡ります。

npm20

npm では原因は最後の六行ではなく最初の code XXXX の一行に書かれており、失敗が自分のコードではなく依存関係の木やネイティブビルドから来ている場合は、node_modules を消して入れ直すだけで半分は解けます。

npm ERR! ERESOLVE unable to resolve dependency treenpm 7 以降は peerDependencies のバージョン範囲が強制されており、それらを同時に満たす組み合わせが見つからなかったという意味です。入れようとしている package の peer 範囲が、すでに使っている react や typescript のバージョンを排除しているときに — とくにメジャー更新の直後に — よく出ます。出力の Found: と Could not resolve: の行を読んで誰が何を要求しているかを見て、どちらか一方を合うバージョンへ動かすのが本当の解決です。npm install --legacy-peer-deps は peer 範囲を丸ごと無視して入れるので当面は進めますが、package たちが同意していない木が残るため、バージョン不一致による実行時エラーは自分で追う必要があります。npm ERR! Conflicting peer dependency: react@18.3.1ERESOLVE の報告の中で実際にぶつかっている一組を抜き出した行です。この package はその peer のそのバージョンを要求しているのに、こちらの木には別のバージョンが入っている、という意味です。多くは本体のライブラリがメジャー更新され、それを使う plugin が追いついていない状態です。npm ls react のように名前で尋ねると、誰がどのバージョンを要求したかが木の形で出て、二つのどちらを動かすべきかがその場で見えます。plugin を新しい版へ上げるのが本当の解決で、--force は食い違った木をそのまま書き込み、問題を実行時まで隠します。npm WARN react-dom@17.0.2 requires a peer of react@17.0.2 but none is installed.npm 6 は peer 依存を警告するだけで代わりに入れてはくれなかったという意味です。その package は入りましたが、それが必要だと言っている相方は入っていません。npm 6 のままのプロジェクトや、その時代に作られた古い lock ファイルをそのまま使っているときに出ます。警告に書かれた範囲に収まるバージョンでその peer を自分で入れれば終わりです。いまは警告なので何も失敗していませんが、後になって Cannot find module として現れたり、同じライブラリが二組入って訳の分からないエラーを出す形で戻ってきます。npm WARN deprecated request@2.88.2: request has been deprecatedその package の作者が、そのバージョンをもう推奨しないと印を付けたという意味です。導入はされ、いまも動きます。多くは自分の package.json に書いたものではなく、自分が使っている package が連れてきた間接的な依存です。npm ls request のように名前で尋ねると、どの直接依存がそれを引き込んでいるかが分かり、直す場所はその直接依存を上げる側で、この package 自体ではありません。今日すぐやることはありません。deprecated はセキュリティ上の脆弱性ではなく、それは npm audit が別に教えてくれます。npm ERR! npm ci can only install packages when your package.json and package-lock.json or npm-shrinkwrap.json are in sync.npm ci は lock ファイルに書かれたとおりにしか入れないので、package.json が lock ファイルに記録されていないものを求めており、始める前に止まったという意味です。誰かが package.json を手で直したり、そのファイルの衝突を解決したのに install を走らせなかった場合、あるいは package.json だけを commit して lock ファイルを一緒に上げなかった場合に出ます。手元で npm install を一度走らせて lock ファイルを合わせ、その lock ファイルを commit すれば、それが直しのすべてです。package-lock.json を消して切り抜けると、すべての依存が新しいバージョンへ解決し直され、ビルドに入る中身が黙って変わります。npm ERR! The `npm ci` command can only install with an existing package-lock.json or npm-shrinkwrap.jsonnpm ci は lock ファイルそのものが無いと一切動かないという意味です。どのバージョンを入れるべきかを書いた場所が無いからです。package-lock.json が .gitignore に引っかかっている、一度も commit されていない、あるいはいま立っているディレクトリがプロジェクトの根ではない、といったときに出ます。npm install --package-lock-only は何も入れずに lock ファイルだけを作るので、それを commit すれば CI が動きます。package-lock.json を .gitignore に入れてはいけません。CI が同じものを二度作れるという保証は、その一つのファイルに掛かっています。npm ERR! Invalid Version:package.json の version の値が正しい semver でないため、npm がその package をまったく読み込めないという意味です。1.0 や v1.0.0、空文字列のように手で書き換えた値のとき、とくにそのファイルの衝突を解決し損ねたときに出ます。npm pkg set version=1.0.0 で三桁のバージョンを書き戻せば済みます。この命令は package.json だけを直し、node_modules も lock ファイルも触らないので、保存後はそのファイルを読むすべての命令がすぐ動き直します。npm ERR! 404 Not Found - GET https://registry.npmjs.org/@acme/ui - Not foundレジストリにその名前の package が無いという意味です。404 は名前についての答えで、ネットワークや資格情報についての答えではありません。名前の打ち間違い、unpublish された package、ログインしていない非公開 scope のときに出ます。非公開の package は権限の無い人には存在しない package と全く同じに見えるので、この三つが一行に重なります。npm view @acme/ui version でその名前が公開されているか先に確かめ、非公開 scope なら .npmrc にその scope のレジストリとトークンが書かれているかを見ます。どちらの確認も読むだけです。npm ERR! request to https://registry.npmjs.org/express failed, reason: unable to verify the first certificateTLS 接続が失敗したという意味です。サーバーが差し出した証明書の連なりが、node の信頼していない機関の署名に行き着いています。圧倒的に多いのは、社内ネットワークのプロキシが通信を開いて自分の証明書で署名し直している場合で、まれにサーバーが中間証明書を一緒に送っていない場合です。npm config set cafile で会社の根の証明書を npm に教えるのが正しい解決です。strict-ssl false でもこの行は消えますが、それは証明書の検査そのものを切ることで、経路上の誰でも書き換えた package を渡せるようになります。使いません。npm ERR! code EINTEGRITY落としてきた圧縮ファイルのハッシュが lock ファイルに記録された値と一致しないという意味です。npm は届いたものを信用できないと判断して止まりました。キャッシュの写しが壊れている、プロキシが落ちてくるファイルに手を加えた、まれに lock ファイルの integrity 値を手で書き換えたか併合を誤った、といった場合です。npm cache clean --force でローカルのキャッシュを空にすれば次の設置で取り直し、これはキャッシュの写しだけを消すので繰り返しても安全です。特定の package でだけ続くなら、記録された integrity 自体が誤っているので、npm install でその項目を解決し直す必要があります。npm ERR! Error: EACCES: permission denied, access '/usr/local/lib/node_modules'npm が自分の利用者の所有でないシステムのディレクトリに書こうとしたという意味です。package が悪いのではなく、その場所に書く権限が無いだけです。ほぼ常に、OS の package 管理者が /usr/local のような場所に置いた node に対して npm install -g をした場合です。npm config set prefix ~/.npm-global で全体設置の場所をホームディレクトリに移し、その中の bin を PATH に入れれば、この誤りは戻ってきません。sudo npm install -g でも通りますが、キャッシュや node_modules に root 所有のファイルを残し、後の普通の設置で同じ EACCES を生みます。nvm のような版管理を使えばこの種類そのものが消えます。npm ERR! enoent ENOENT: no such file or directory, open '/home/me/package.json'npm がいまのディレクトリとその上を辿って package.json を探したが一つも無かったという意味です。プロジェクトでない場所で npm の命令を打ちました。モノレポの根に立っているのにプロジェクトが下のフォルダにある場合、clone したフォルダの隣に立っている場合、単に cd を忘れた場合に出ます。package.json のあるフォルダへ移るのが答えで、ls で目で確かめるのが一番早いです。npm init -y は本当にここで新しいプロジェクトを始めるつもりのときだけ使います。誤ったフォルダで走らせると、残った package.json が後で道具たちを惑わせます。npm ERR! code ELIFECYCLEpackage.json の script の一つが 0 以外のコードで終わったという意味です。ELIFECYCLE はそれを包んだ npm の外皮であり、原因ではありません。原因は自分の build や test の script がしたことで、本当の誤りの行はこの行より上にあります。上へ遡って最初の誤りを探すか、npm ERR! <pkg>@<ver> <script>: の後に出ている実際の命令をそのまま手で走らせれば、npm の外皮なしに元の出力が見られます。後に続く終了コードも少し教えてくれます — 1 は普通の失敗、137 はたいていメモリのために処理が強制終了されたことです。gyp ERR! build error依存の中に C や C++ の部分があり、設置時にその場でコンパイルする必要があるのに、そのコンパイルが失敗したという意味です。node-gyp はコンパイラと python を必要とします。ビルド道具がまったく入っていない場合、あるいはその package が自分の node より古くヘッダが合わない場合に出ます。macOS では xcode-select --install でコマンドライン道具を、Debian・Ubuntu では build-essential と python3 を、Windows では Visual Studio の C++ ワークロードを入れます。その package の新しい版が自分の node 用の事前ビルド済み実体を配っているなら、ビルド環境を直すより package を上げるほうがはるかに速いです。Error: Cannot find module 'express'node がその名前をどのファイルにも解決できなかったという意味です。node_modules の中に無いか、node_modules の無いディレクトリで走らせています。まったく設置していない、設置が途中で失敗して木が半分しかできていない、その package が devDependencies にあるのに --omit=dev で入れた、といったときに出ます。rm -rf node_modules && npm install は lock ファイルから木を作り直し、安全で失うものは無く、掛かるのは取得の時間だけです。ただし引用符の中の名前が ./ で始まる相対経路なら、package が欠けているのではなく自分のコードの経路が誤っています。Module not found: Error: Can't resolve './components/Button' in '/app/src'束ね役がその経路にそのファイルを見つけられなかったという意味です。これは package ではなく自分が書いた import です。相対経路が一段ずれている、拡張子が抜けているか誤っている、ファイル名の大文字小文字が import と違う、といったときに出ます。最後のものが最も厄介で、macOS と Windows のファイルシステムは大文字小文字を区別しないため、自分の機械では動き Linux の CI でだけ壊れます。そのディレクトリを ls で出し、import と一文字ずつ、大文字小文字まで照らし合わせます。名前が経路ではなく package なら入れれば済み、どちらの場合も消えるものはありません。Error: error:0308010C:digital envelope routines::unsupportednode 17 が OpenSSL 3 を載せた際に古いハッシュ算法が既定から外れ、それを求める道具がハッシュを呼ぶその場で倒れたという意味です。ほぼ常に、古い webpack 4 か、それを内に抱えた道具を今の node で走らせている場合です。export NODE_OPTIONS=--openssl-legacy-provider はその処理に限って古い算法を再び有効にし、ビルドに使う分には害がありません。ただしそれは死んだ道具を無理に生かしているので、webpack 5 か枠組みの現行版へ上げれば、この選択肢自体が不要になります。FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memoryV8 のヒープが上限に達し、node が自ら諦めたという意味です。OS が殺したのではなく、node がこれ以上増やせないと判断して止まりました。大きなプロジェクトの型検査や束ね、ソースマップを入れたビルド、あるいは何でも配列に溜め込むような漏れのあるコードが原因です。export NODE_OPTIONS=--max-old-space-size=4096 で上限を 4 GB まで上げれば多くは通りますが、機械に実際その分の記憶が要り、コンテナの制限がより低ければ今度は OS が処理を殺し、終了コード 137 として現れます。数字を上げ続けなければならないなら、原因は上限ではなく漏れです。npm WARN EBADENGINE Unsupported engineある package が engines に書いた node や npm のバージョン範囲を、こちらの環境が満たしていないという意味です。npm は警告するだけでそのまま入れます。システムの package として入った古い node を使っている場合や、プロジェクトが自分のシェルの node より新しい版へ移った場合に出ます。版管理でその範囲に入るバージョンへ node を切り替えればよく、信じる基準はプロジェクトの .nvmrc か package.json の engines です。既定では警告にすぎませんが、.npmrc に engine-strict=true があると、同じ条件が設置を止める誤りに変わります。zsh: command not found: tscシェルが PATH を辿ったが、その名前の実行体を見つけられなかったという意味です。設置そのものは成功しているかもしれません。npm の全体用 bin ディレクトリが PATH に無い、全体ではなく手元に入れたので実行体が node_modules/.bin に入った、シェルが古い PATH を覚えている、といったときに出ます。npx tsc --version は PATH に一切触れず手元の写しを走らせるので、その一行で「入っていない」と「PATH に無い」を切り分けられます。本当に全体へ入れたのなら、npm prefix -g の出力に /bin を足した経路を PATH に加え、シェルを開き直します。

JavaScript15

ブラウザと node の誤りは、たいてい何が壊れたかだけを告げ、なぜその値がそうなったかは告げません — undefined を読んだ、関数ではなかった、JSON ではなかった。ですから直す場所は投げた行ではなくその値を作った上流であり、?. や既定値でその行だけ黙らせると、同じ問題がもっと遠くで、もっと分かりにくい形で戻ってきます。

Uncaught TypeError: Cannot read properties of undefined (reading 'name')ドットの左の値が undefined なのに、その属性を読もうとしたという意味です。丸括弧の中の名前が読みたかった属性なので、壊れているのはその前の値です。まだ届いていない応答、誰も渡していない prop、data.user.name のように一段深く踏んだ場所、空の配列に対する arr[0].id が典型です。値が無くてもよい場所なら user?.name で短く切れますが、本来あるべき値だったなら ?. は誤りを undefined に変えて次の行へ先送りするだけです — なぜ undefined なのかを上流で探してください。Chrome 78 より前は同じ誤りが Cannot read property 'name' of undefined と出ていました。TypeError: items.map is not a functionその名前はあるが関数ではないという意味で、名前自体が無ければ文言は undefined 側に出ます。配列だと思っていたものが実はオブジェクトや NodeList だった、API が配列ではなく {data: [...]} を返した、import したモジュールの既定エクスポートの形を取り違えた、が典型です。推測より先に出力してください — console.log(typeof items, items) の一行でこの誤りの半分はその場で終わります。NodeList や Set なら Array.from(items) で包めば済みますが、{data: [...]} だったなら包むのは間違いで、items = res.data と直すのが正解です。RangeError: Maximum call stack size exceeded呼び出しが積み上がる深さがエンジンの上限を超えたという意味で、多くは深い再帰ではなく終わらない再帰です。止める条件が無いか届かない関数、互いを呼び合う二つの関数、自分自身を含むオブジェクトを JSON.stringify に渡す場合、React なら描画中に自分が依存する状態を変える場合が原因です。コンソールのスタックで繰り返されている二、三のフレームがそのまま輪なので、そこに基底条件を置いてください。本当に深さが必要な計算なら、再帰をループか明示的なスタックに書き換えるのが唯一の道です — ブラウザのスタック上限は上げられません。SyntaxError: Unexpected token '<', "<!DOCTYPE "... is not valid JSONJSON.parse に渡したものが JSON ではなく HTML だったという意味です。文言に残る <!DOCTYPE の断片が証拠で、サーバが 404 や 502、ログインへのリダイレクトページを HTML で返したことを示します — つまり本当の誤りは解析ではなく、その前の要求にあります。URL が違う、開発サーバのプロキシが API ではなく index.html を返した、認証が切れてログイン画面へ飛ばされた、が典型です。res.json() を呼ぶ前に res.ok を見て、違えば res.text() で実際に何が来たかを読んでください — その URL を curl -s で直接叩くのが一番速いです。Chrome 111 と Node 20 より前は同じ誤りが Unexpected token < in JSON at position 0 と出ていました。SyntaxError: Unexpected end of JSON inputJSON を読んでいる途中で文書が終わってしまったという意味で、ほぼ必ず本文がそもそも空でした。204 No Content や本文の無い誤り応答に res.json() を呼んだ、応答の本文を既に一度読んで二度目に空が来た、書きかけで切れたファイルを読んだ、のいずれかです。まずテキストとして受けて空かどうかを見てから解析すると、正確な診断になります — const t = await res.text(); if (!t) return null;。JSON.parse(text || 'null') のように既定値で覆うと空の応答が正常に見えてしまうので、サーバがなぜ空の本文を返したのかを先に確かめてください。TypeError: Failed to fetch要求が応答を受け取らずに終わったという意味で、ブラウザが理由をあえて隠した文言です — CORS で塞がれた、宛先が死んでいる、証明書が不正、広告ブロック拡張が切った、が全て同じ言葉になります。これは状態ではなく投げられた誤りなので 404 や 500 はここまで来ません。サーバは応答を始めることさえできなかったのです。コンソールのこの行の上や Network タブに、より具体的な一行がある場合が多いのでそれを先に読み、curl -i でその URL を直接叩けば「サーバが落ちている」と「ブラウザが拒んだ」が分かれます。Firefox では同じ状況が NetworkError when attempting to fetch resource と出ます。Access to fetch at 'https://api.example.com/data' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.要求はサーバに届き応答も返ってきたのに、その応答にこの出所を許す見出しが無く、ブラウザが JavaScript へ渡すことを拒んだという意味です。この規則を守るのはブラウザだけなので、同じ URL を curl で叩けば通ります — だからサーバは無事でブラウザだけが壊れているように見えます。直す場所は常にサーバ側で、応答に Access-Control-Allow-Origin: http://localhost:3000 を付けることです。フロントエンド側にできることは何もなく、他人のサーバなら自分のサーバを経由して呼ぶプロキシが唯一の道です。Allow-Origin: * は cookie を送る要求では通らず、その場合は出所を正確に書いて Allow-Credentials も有効にする必要があります。SyntaxError: Cannot use import statement outside a modulenode かブラウザがそのファイルを CommonJS のスクリプトとして読み、その中に ESM の構文である import があったという意味です。.js は package.json に type の宣言が無ければ CommonJS として読まれ、ブラウザでは <script> に type="module" が無いときに同じことが起きます。npm pkg set type=module でそのパッケージ全体を ESM と宣言すれば解けますが、その瞬間からそのパッケージのすべての .js で require と __dirname が使えなくなるため、残りの CommonJS のファイルも一緒に移す必要があります — 一つのファイルだけ移したいなら、拡張子を .mjs に変えるほうが狭くて安全です。ReferenceError: require is not defined in ES module scope, you can use import instead先の誤りのちょうど裏返しです — このファイルは ESM として読まれているのに、中に CommonJS の require があります。package.json に "type": "module" を入れた直後、古いスクリプトがそのまま残っているときにほぼ必ず起きます。そのファイルだけ古い世界に置くなら mv script.js script.cjs と拡張子を変えるのが最小の修正で、ESM へ移すなら require を import に書き換えると同時に、ESM に存在しない __dirname や require.main === module も直す必要があります。Error [ERR_MODULE_NOT_FOUND]: Cannot find module '/app/src/util' imported from /app/src/index.jsnode が ESM を実行するときは、ブラウザと同じように import の経路をそのままファイル名として扱うので、'./util' は './util.js' ではなく存在しないファイルです。CommonJS では node が拡張子を補って探してくれ、TypeScript は拡張子なしの import をコンパイル後もそのまま残すため、tsc で組んだプロジェクトを初めて node で動かすとこの誤りが大量に出ます。相対経路の import に .js を付けてください — TypeScript のファイルの中でも './util.js' と書くのが正しいです(node が読むのはコンパイル結果だからです)。node_modules のパッケージ名には拡張子を付けません。ReferenceError: window is not definedそのコードがブラウザではなくサーバの node の中で動いたという意味です。node には window も document も localStorage も無いので、Next.js や Nuxt のように先にサーバで描画する枠組みでモジュールを読み込む時点で window を触ると、ここで止まります — コンポーネントの外に置かれた一行や、ブラウザ専用ライブラリの import そのものが原因のことが多いです。ブラウザだけの処理なら typeof window !== 'undefined' で囲むか、より良くはそのコードを useEffect の中へ移してください — 効果はブラウザでしか動かないからです。ライブラリ全体がブラウザ専用なら、Next.js では dynamic(() => import('./C'), { ssr: false }) でサーバ描画から外すのが答えで、その代わりその部分はサーバが作る HTML に含まれません。Hydration failed because the initial UI does not match what was rendered on the serverサーバが送ってきた HTML と、ブラウザが最初の描画で作った結果が違うため、React が両者を繋げられなかったという意味です。描画の中で new Date() や Math.random() を使う、localStorage を読む、window の幅で描き分ける — これらは必ずサーバとブラウザで答えが変わります。<p> の中に <div> を入れたようにブラウザがタグを直してしまう場合も同じ結果です。最初の描画ではサーバと同じものを描き、変わる部分は useEffect が走った後で変えるのが定石です。その代償として、その部分は一瞬遅れて現れ、サーバの HTML には含まれません。React 19 では同じ状況が "the server rendered HTML didn't match the client" と書かれ、どこが違ったかの差分まで出ます。Objects are not valid as a React child (found: object with keys {name, id})描画するよう渡した値が文字列や数値ではなくオブジェクトだという意味で、丸括弧の中の鍵の一覧がそれが何かを教えます。{user} と書いた場所が本来 {user.name} であるべきか、応答全体をそのまま描こうとした場合です。鍵の一覧ではなく found: [object Promise] と見えたら原因が違います — await を忘れて async 関数の結果を描こうとしたのです。描くフィールドを選んで書くのが答えで、調査中なら JSON.stringify(user) で一時的に見られますが、それを画面に残さないでください。Each child in a list should have a unique "key" prop.一覧として描いた兄弟要素に key が無く、次の描画でどれがどれか React が対応付けられないという意味です。items.map(...) で要素を作りながら key を落としたのが原因で、これは警告なので画面はいったん描かれますが、一覧が変わったときに静かな不具合として返ってきます — 入力欄の値やアニメーションが違う行に残るのがその症状です。データにある安定した id を key に渡してください。配列の添字を key にするのは、順序が絶対に変わらず、途中で挿入も削除もしない一覧でのみ安全で、そうでなければ key が無いのとほぼ同じ問題を起こします。React 19 からは先頭に付いていた Warning: が無くなりました。Too many re-renders. React limits the number of renders to prevent an infinite loop.描画が状態を変え、その状態がまた描画を呼ぶ輪に入り、React が無限反復を防ぐために断ち切ったという意味です。ほぼ必ず、関数を渡すべき場所で関数を呼んでいます — onClick={setOpen(true)} は描画のたびに即実行されるので、onClick={() => setOpen(true)} でなければなりません。他によくある形は、描画の本体で直接状態を変えること、そして useEffect の依存一覧に自分が更新する値を入れることです。状態の変更はイベント処理か useEffect の中へ移し、描画中に計算するだけで済む値なら、そもそも状態にする必要があるか考え直してください。

Python18

Python のトレースバックは答えを二つに分けて置きます — 最後の一行が何が誤りかを、その上のフレームがどこで誤ったかを示すので、最後の行だけ読むと名前は分かって場所を落とします。とくに NoneType や KeyError のように値が無くて出る誤りは、落ちた場所より、その値を作った上のフレームに原因があります。

ModuleNotFoundError: No module named 'requests'sys.path にあるディレクトリを全部見たが、その名前のモジュールが無いという意味です。まだ入れていないか、入れた先が別のインタープリタであるかのどちらかで、仮想環境の外で pip install して中で実行すると必ずこうなります。python -m pip install と書けば今動かしているインタープリタに直接入るので、このずれは消えます。error: externally-managed-environmentこの Python は OS か Homebrew が管理しているもので、pip がそこへ書き込むのを拒んでいます(PEP 668)。システムのインタープリタに対して pip install したのが原因で、このメッセージは「仮想環境を作れ」という案内です。--break-system-packages は名前のとおりシステム側のパッケージを壊しうるので、.venv を作ってそこに入れるのが答えです。ImportError: cannot import name 'User' from partially initialized module 'models' (most likely due to a circular import)二つのモジュールが互いを import しているため、まだ半分しか読み込まれていないモジュールから名前を取り出そうとしています。A が B を、B が A を呼ぶ形で起こり、ファイルを分けた直後に型ヒントのために import を戻すときによく出ます。from y import Thing を import y に変え、関数の中で y.Thing と書けば参照が後ろにずれ、循環が問題になりません。IndentationError: unexpected indentその行が前の行より深く入っているのに、深くしてよい理由になるコロンが上にありません。貼り付けたコードが自前の字下げを連れてきたか、if の行を消して中身だけ字下げのまま残した場合が多いです。エラーが指す行の先頭の空白を取れば直り、見分けがつかないときは cat -A でその行を出すと空白とタブが見えます。TabError: inconsistent use of tabs and spaces in indentation一つのブロックの中でタブと空白が混ざっており、どの行が深いのかを Python が決められません。タブを入れる編集器から貼り付けたときや、二人が別々の設定で同じファイルを触ったときに起こり、画面上は全く同じに見えるので目では見つかりません。python -m tabnanny app.py がずれた行番号を出し、あとはそのファイルを編集器で空白四つに統一すれば終わりです。SyntaxError: invalid syntaxその位置で文として読み進められなかったという意味で、原因は指された行ではなく多くはその前の行にあります。閉じていない括弧や引用符、抜けたコロン、Python 2 の print "x" が主な原因で、括弧が開いたままだとパーサは何行も進んでから諦めます。python -m py_compile app.py なら実行せずに文法だけ確かめられ、3.10 以降は文言がずっと具体的になるので、Python を上げること自体が診断になります。TypeError: 'NoneType' object is not subscriptable[...] で取り出そうとしたその値が None だという意味です。上流の何かが黙って None を返しており、鍵の無い dict.get() や一致しなかった re.match、通った経路に return が無い関数が典型です。落ちた場所で None を弾くより、なぜ None なのかを上へ辿ってください — None を飛ばす if を一つ足しても、同じ誤りが次の行に移るだけです。AttributeError: 'NoneType' object has no attribute 'get'ドットの左のオブジェクトが None なので、求めた属性やメソッドが存在しません。前の nonetype-not-subscriptable と根は同じで、見つからなければ None を返す関数、たとえば BeautifulSoup の find() や re.search() の結果にそのまま続けて書いたときに特に出ます。まずその関数が何を探していたのかを出力し、見つからないのが正常な場合はその分岐を明示的に扱ってください。KeyError: 'name'その鍵が dict に無いという意味です。引用符の中がまさに探した鍵なので、まずそこを見てください — 打ち間違い、大文字小文字の違い、あるいは API 応答の形が思っていたものと違う場合です。無くてもよい値なら d.get("name") で None が返り、d.get("name", 0) で既定値を渡せますが、必ずあるべき値に .get を使うと、誤りの代わりに None がコードの奥へ流れ、ずっと遠くで壊れます。IndexError: list index out of rangeリストに無い位置を番号で呼びました。長さが n なら最後の番号は n-1 なので、range(len(x) + 1) や x[len(x)] は必ずここで止まり、空のリストに x[0] をするのも同じ誤りです — 前段の絞り込みや split が何も残さなかったときによく起きます。番号で回す代わりに for item in items: で回せばこの種の不具合は構造的に消え、位置が本当に必要なら enumerate(items) を使ってください。ValueError: invalid literal for int() with base 10: '3.5'int() に整数として読めない文字列を渡しました。引用符の中がその文字列です。'3.5' のような小数点、空文字列、改行の付いた入力、'1,000' のような桁区切りが主な原因です。小数点なら int(float(s)) の二段で通りますが、四捨五入ではなく小数部が切り捨てられます。人が打ち込む値なら、最初から try/except ValueError で包むほうが正直な対処です。UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 0: invalid start byteファイルやバイト列を UTF-8 として読もうとして、UTF-8 では許されないバイトに当たったという意味です。位置とバイト値が文言に書かれており、多くは Windows から来た cp1252 や euc-kr の CSV、そもそもテキストでない画像や zip、解凍し忘れた gzip です。本当のエンコーディングを調べて encoding= で渡すのが正解で、errors="replace" は読み終えられますがそのバイトが疑問符に変わり、データは静かに壊れたまま先へ進みます。ZeroDivisionError: division by zero0 で割ったという意味です。実際には定数の 0 ではなく、数えた件数が 0 だった場合がほとんどで、平均を出すコードで一覧が空だったり絞り込みが何も残さなかったときが典型です — 開発用のデータでは必ず通り、本番で初めて落ちる種類です。割る前に分母が 0 かを見て、0 のとき何を返すかを決めてください。0 を返す、None を返す、例外をそのまま上げるは別々の判断で、それぞれが正しい場面があります。RecursionError: maximum recursion depth exceeded関数が自分を呼ぶ深さが既定の上限 1000 を超えたという意味です。本当に深い計算よりも、止める条件が無いか届かない場合のほうがずっと多く、__getattr__ や property の中で自分の属性をまた読むような間接再帰もここに来ます。まずトレースバックで繰り返されている二、三のフレームを見つけて基底条件を直してください。sys.setrecursionlimit() で上限は上げられますが、本物の C スタックを踏み越えられるようになり、例外ではなく Python 自体が丸ごと落ちます — ループに書き換えるほうが安全です。UnboundLocalError: cannot access local variable 'count' where it is not associated with a value関数の本体のどこかでその名前に代入していると、Python はその名前を関数のローカル変数と決めます。つまり代入より前に読んだということです。外側の同名の値が見えると思っていた場合や、count += 1 のように読んで書く演算を初めて書いたときに出ます。関数の中で count = 0 から始めるのが普通の答えで、本当にモジュール側の値を変えたいなら global count と書けますが、その値を誰が書き換えるのか追いにくくなる代償が付きます。3.10 までは同じ誤りが 'local variable referenced before assignment' と出ていました。TypeError: greet() takes 1 positional argument but 2 were given受け取る約束より一つ多く渡したという意味で、数の差がちょうど一つなら、ほぼ必ず self です。クラスの中のメソッドを def greet(name): と定義すると、obj.greet("x") を呼んだ時点で Python が obj を最初の引数として渡すため、引数は二つになります。メソッドなら def greet(self, name): と self を受け取る形に直し、インスタンスが不要な関数なら @staticmethod を付けてください。PermissionError: [Errno 13] Permission deniedその経路に対するその操作を OS が拒みました。/var/log や /usr のように他人の所有する場所に書こうとした、コンテナで host のボリュームの UID がコンテナのユーザと違う、あるいは見落とされがちですが、ファイルではなくそれを収めるディレクトリに書き込み権限が無い — 新しいファイルを作るにはディレクトリの権限が要ります。まず ls -ld で所有者とモードを確かめ、sudo に頼る前に書ける場所へ経路を移すことを考えてください。sudo で作ったファイルは、次に sudo 無しで開くとまた同じ誤りを出します。OSError: [Errno 98] Address already in useそのポートを既に別のプロセスが握っているため bind に失敗したという意味です。前のサーバが完全に終わっていない、自動再読み込みが二つ立ち上げた、同じポートを Docker のコンテナが既に公開している、のいずれかです。lsof -i :8000 で握っている PID が分かるのでそれだけ片付ければよく、kill -9 で手当たり次第に消す前にプロセス名を確かめてください。errno は OS ごとに違い、Linux では 98、macOS では 48 と出ます。

ビルドと型10

ビルドの誤りは実行前に道具が拒んだものなので、その場で何かを壊すわけではありません。代わりに二つを問います — 型や経路を実際の形に合わせて直すのか、それとも as any や抑制のコメント一つでその行だけ通すのか。そして大文字小文字や拡張子、環境変数のように自分の環境でだけ正しいものは、ここで初めて姿を見せます。

error TS2307: Cannot find module 'lodash' or its corresponding type declarations.tsc がそのモジュール自体も、そのモジュールの型宣言も見つけられなかったという意味で、文言が両方を言っているのが肝心です — パッケージがそもそも無い場合も、入っているが型だけ無い場合もあります。入れてあるのにこう出るなら型のほうなので、npm i -D @types/lodash のように対になる型パッケージを入れます。ただし近年のパッケージは型を同梱しており @types が存在しないことも多いです。相対経路の import でこれが出たら、大文字小文字と tsconfig の paths を見てください — 自分のファイルを指す経路は @types と無関係です。error TS2339: Property 'user' does not exist on type 'Request'.その型にその属性が宣言されていないという意味です。ライブラリの型に無いフィールドを足そうとした場合(Express の Request に user を付けるのが代表例)、打ち間違い、あるいは絞り込まれていない union の片方にしか無い属性を読んだ場合に出ます。型を実際の形に合わせて直すのが答えで、union なら 'x' in y や判別用のフィールドで絞れば、その分岐の中では参照できます。as any で消すのはコンパイラの口を塞ぐだけなので、その場所は綴りを間違えた属性名まで通すようになります。error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.関数が受け取る型と渡した値の型が違うという意味で、文言が順に書いてくれます — 前が渡したもの、後ろが受け取るはずのものです。最も多いのは、フォームの入力値や URL のクエリ文字列、JSON から来た値が文字列のまま数値を受け取る場所に入る場合です。境界で一度変換するのが答えですが、Number(value) は失敗しても例外ではなく NaN を返すので、その NaN が流れていかないよう検査が必要です — Number.isFinite(n) がその場所です。error TS18048: 'user' is possibly 'undefined'.その値が undefined かもしれないのに、その可能性を扱っていないという意味で、これは tsc が先回りして捕まえた将来の Cannot read properties of undefined です。省略可能なフィールド、配列の find() の結果、設定されていないかもしれない環境変数にそのまま続けて書いたときに出ます。無いときにどうするかを決めるのが答えで、関数の頭で if (!user) return null と切るか、user?.name で短く抜けます。感嘆符を付けて user!.name と消すのは「私が保証する」という宣言で、その保証が誤っていれば実行時の例外として返ってきます — 検査と違い、安全網を何も残しません。error TS7006: Parameter 'req' implicitly has an 'any' type.引数に型が書かれておらず、tsc が推論する手がかりも無かったため暗黙に any になったという意味で、noImplicitAny が有効ならそれを誤りとみなします。JavaScript から移したファイルや、コールバックを別の変数に取り出したときに出ます。逆に items.map(x => ...) のように文脈のある場所では tsc が推論するので、これは出ません。そこに型を書くのが答えです。any と明示して通すこともできますが、それはその引数について検査を完全に切る選択です — 何か分からないときは unknown のほうが正直で、使う前に絞ることを強制します。Parsing error: Unexpected tokenESLint がそのファイルに規則を当てる前、文法を読む段階で止まったという意味です。本当にコードが壊れている場合より、パーサがその文法を知らない場合のほうがずっと多いです — TypeScript のファイルを既定のパーサで読んだ、JSX を有効にしていない、デコレータやごく新しい文法を古いパーサに渡した、などです。npx eslint --print-config app.ts をそのファイルに対して走らせると、実際に適用される parser と parserOptions がそのまま出るので、当てずっぽうより先にそれを見てください。TypeScript なら @typescript-eslint/parser が必要で、そのファイルをそもそも検査しないのなら ignores に入れるのが正解です。You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file.webpack が Module parse failed の後に付ける行で、そのファイルを JavaScript として読もうとしたが JavaScript ではなかったという意味です。TypeScript や JSX、CSS、画像、.vue のように変換が必要なファイルを module.rules に規則無しで import したか、node_modules のパッケージが未コンパイルのソースを配っていて、そのフォルダが exclude に入っている場合です。その拡張子に合う loader の規則を module.rules に足すのが答えで、どのファイルで止まったかは文言の上に出る経路が教えます。exclude: /node_modules/ を消して片付けるとビルド全体が目に見えて遅くなるので、そのパッケージ一つだけを例外にするほうが良い取引です。Failed to resolve import "./utils" from "src/main.ts". Does the file exist?その経路にファイルが見つからなかったという意味で、一緒に出る "Does the file exist?" が本当に確かめるべき三つを指しています — 名前の大文字小文字、拡張子、そして tsconfig や vite.config の別名です。macOS と Windows のファイルシステムは大文字小文字を区別しないので、./Utils と書いても自分の環境では動き、Linux で動く CI と配備で初めて壊れます — この誤りが「自分の環境では動く」の最も多い正体です。git ls-files src | grep -i utils でリポジトリに実際どの綴りで入っているかを確かめてください。別名(@/utils)なら vite.config の resolve.alias と tsconfig の paths の両方を合わせる必要があり、片方だけ直すと編集器は黙るのにビルドだけ壊れ続けます。You're importing a component that needs useState. This React hook only works in a client component.App Router では全てのコンポーネントが既定でサーバコンポーネントであり、useState のようにブラウザでしか意味を持たないフックを使うファイルを、サーバコンポーネントが import したという意味です。指示子はファイルの一番上の 'use client' 一行で、付けるとそのファイルとそれが import する全てがクライアントの束に入ります — だからページ全体ではなく、状態が必要な最小の断片にだけ付けるのが安い選択です。逆向きに、クライアントコンポーネントが子としてサーバコンポーネントを受け取る形に分ければ、データ取得はサーバに残せます。Next.js 13 では同じ状況が "It only works in a Client Component but none of its parents are marked with \"use client\"" と書かれていました。The engine "node" is incompatible with this module. Expected version ">=20"入れようとしているパッケージが package.json の engines に必要な node の版を書いており、今使っている版がその範囲の外だという意味です。後ろに付く Expected と Got が要求範囲と自分の版を並べて見せるので、その二行だけ見れば足ります — CI でだけ出るなら、そこの node の版が自分の環境と違うということです。nvm install 20 && nvm use 20 で node を上げるのが正面の答えで、.nvmrc や CI の設定にも同じ版を書いておけば次にまたずれません。yarn の --ignore-engines で押し通せますが、それは警告を消すだけで互換性を作らないので、そのパッケージが新しい構文を使えば実行中に構文誤りとして落ちます。npm は同じ状況を EBADENGINE の警告として知らせ、既定では設置を止めません。

Docker12

docker の誤りは、まずどの層で起きたかを分けないと読めません — クライアントがデーモンに届かない、レジストリが拒む、ビルド中に RUN が失敗する、コンテナが起動した途端に死ぬ、はそれぞれ別の問題です。とくにビルドと実行の層では文言そのものが理由ではなく、中で動いていた命令が残した出力に理由があり、直す命令の代償も層ごとに違います。

Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?docker コマンド自体は何もせず、そのソケット越しにデーモンへ頼むだけで、誰も応えなかったという意味です。デーモンが止まっている、macOS や Windows で Docker Desktop の起動が終わっていない、Linux で自分のユーザが docker グループに居らずソケットを開けない — この三つが同じ一行になります。Linux なら sudo systemctl start docker で起こし、Desktop ならまずアプリを立ち上げてください。権限側なら sudo usermod -aG docker $USER の後に再ログインが要りますが、そのグループは実質 root と同じ力を与えます。Bind for 0.0.0.0:8080 failed: port is already allocated-p でホスト側のそのポートを取ろうとしたが、別のコンテナやプロセスが既に使っているという意味です。以前 --rm を付けずに起こしたコンテナが停止したまま残っている、compose が古いコンテナをまだ握っている、が大半です。docker ps --filter publish=8080 がそのポートを公開しているコンテナをそのまま指し、コンテナでなくホストの別のプログラムなら lsof -i :8080 で見つかります。急ぐなら -p 8081:80 のようにホスト側の番号だけ変えても動きますが、古いコンテナを片付けなければ次も同じことが起きます。Conflict. The container name "/api" is already in use by container--name で渡した名前を既に別のコンテナが使っているという意味です。名前は動いているコンテナだけでなく停止したコンテナも含めて一つだけなので、昨日死んだコンテナがその名前を握り続けている場合がほとんどです — docker ps には出ず docker ps -a にだけ出ます。docker rm -f api でそのコンテナを消せば名前は空きますが、そのコンテナだけにあった書き込み層も一緒に消えます(名前付きボリュームは残ります)。使い捨てのコンテナなら最初から docker run --rm で起こせば、この事態は起きません。failed to register layer: Error processing tar file(exit status 1): no space left on deviceイメージの層を展開する場所がディスクに無いという意味です。多くの場合プロジェクトが大きいのではなく、docker が数か月分の古いイメージとビルドキャッシュ、削除したコンテナのボリュームを抱え続けているだけです。docker system df がイメージ・コンテナ・ボリューム・ビルドキャッシュ別の使用量と回収可能な量を示すので、まずそれを読んでください。docker system prune は停止したコンテナ、ぶら下がったイメージ、使われていないネットワーク、ビルドキャッシュを消し、キャッシュが消えた次のビルドは明らかに遅くなります。--volumes を付けるとコンテナに繋がっていないボリュームまで消え、人がデータベースを失うのはまさにここです。pull access denied for myapp, repository does not exist or may require 'docker login'レジストリがそのリポジトリを見せなかったという意味で、要点はこの文言が二つの原因を同時に言っていることです — 名前が無いか、あるが自分に権限が無いか。非公開リポジトリにログインしていない、名前からユーザや組織が抜けている(myapp と myorg/myapp は別のリポジトリです)、あるいは名前そのものが間違っている場合です。非公開なら docker login でそのレジストリに入り、公開のはずなのにこう出るなら綴りを見直してください。レジストリは「無い」と「見せない」をあえて区別しません — 名前の有無そのものが情報になるからです。manifest for myapp:v2 not found: manifest unknownリポジトリは見つかったが、そのタグが中に無いという意味です。前の pull access denied と違い、こちらは名前が合っていた合図なので、あとはタグだけを見ます — 消されたか移されたタグ、latest だけ上げて v2 を作らなかったパイプライン、あるいはそのタグに自分のアーキテクチャ用のイメージが無い場合です。docker manifest inspect myapp:v2 でそのタグが実際に解決するか、どの platform が入っているかを確かめられます。latest に替えて通り過ぎるのは再現できないビルドを作る代償を払うので、タグを直すほうが良いです。unauthorized: incorrect username or passwordレジストリが送った資格情報を拒んだという意味です。打ち間違いより多いのは、もはやアカウントのパスワードを受け付けないレジストリにパスワードを送った場合です — Docker Hub は二要素を有効にするとアクセストークンしか受け取らず、GitHub や GitLab のレジストリは初めからトークンかデプロイキーだけを受け取ります。docker logout で保存された資格情報を消し、トークンで改めて docker login してください。echo $TOKEN | docker login -u user --password-stdin と渡せば、トークンがシェルの履歴に残りません。failed to solve: process "/bin/sh -c npm ci" did not complete successfully: exit code: 1Dockerfile のその RUN 行が 0 でない状態で終わったという意味です。ここに書かれているのは失敗した命令と終了コードだけで、本当の理由はその上に流れたその命令自身の出力にありますが、BuildKit は終わった段階を畳んでしまうので見えにくいです。docker build --progress=plain で走らせ直すと全段階の出力がそのまま出ますし、キャッシュされた層が古い失敗を隠しているなら --no-cache も付けてください — 代わりに最初の段階から作り直すので時間がかかります。exit code: 1 は理由ではなく、その命令が失敗したという事実だけです。COPY failed: file not found in build context or excluded by .dockerignoreCOPY はビルドコンテキストの中のものしか持ってこられず、その場所にそのファイルが無いという意味です。コンテキストは docker build の最後の引数なので、上の階層のファイルを ../x で指したか、.dockerignore がそのファイルを除いた場合がほとんどです — node_modules や *.env を除外しておいて、その中のファイルを COPY しようとするのが典型です。文言が二つの原因を併記するので、まず cat .dockerignore を読み、経路をコンテキストの根から書き直してください。コンテキストを広げて解決すると、そのフォルダ全体がデーモンへ送られ、ビルドが遅くなります。exec /usr/local/bin/entrypoint.sh: exec format errorカーネルがその実行ファイルのヘッダを認識できなかったという意味で、今ではほぼ必ずアーキテクチャの食い違いです — Apple Silicon で作った arm64 のイメージを amd64 のホストで動かした、あるいはその逆です。シェルスクリプトで一行目の #!/bin/sh が抜けている場合も同じ文言が出ます。docker build --platform=linux/amd64 で焼くのがよくある対処ですが、それは食い違いを消すのではなくエミュレーションで覆う手です — QEMU を通る実行は本来のアーキテクチャより数倍遅くなります。長く使うイメージなら、buildx で両方のアーキテクチャを焼くのが実行時に代償の無い道です。standard_init_linux.go: exec user process caused: no such file or directoryコンテナが入口を実行しようとして、カーネルが「そんなファイルは無い」と答えたという意味で、ファイルは確かにそこにあるのにこう出るのが罠です。スクリプトの行末が CRLF なので一行目が #!/bin/sh\r と読まれ、カーネルは sh\r という名前の実行ファイルを探して失敗します — Windows でクローンしたり git の autocrlf が有効だとこうなります。dos2unix entrypoint.sh でそのファイルだけ直せ(無ければ sed -i 's/\r$//' entrypoint.sh)、再発を止めるには .gitattributes に *.sh text eol=lf と書きます。alpine のイメージに無いインタープリタを #! に書いた場合も同じ文言です。OCI runtime create failed: exec: "bash": executable file not found in $PATH: unknownコンテナは作られたが、その中で実行するよう頼んだプログラムが $PATH に見つからなかったという意味です。alpine 系のイメージには bash が無く sh だけなので、docker run -it myapp bash や CMD ["bash", ...] はまさにこの誤りで終わります — コンテナの中にあると思っていた道具が実はホストにしか無い場合も同じです。docker run --rm -it myapp sh で入ってみれば、そのイメージに何があるのかすぐ分かります。どうしても bash が必要なら Dockerfile に RUN apk add --no-cache bash を入れられますが、イメージが大きくなる代償が付きます。

エラーメッセージの読み方

  • 一行目から読みます。下に行くほど道具の内部の話で、原因はたいてい一番上に書かれています。
  • ファイル名と行番号があればそこが出発点です — スタックの最上段ではなく、自分が書いたファイルが出てくる一番上の行です。
  • 文句はそのまま検索します。ただし自分のパスや変数名は消します — その部分が検索を邪魔します。
  • 同じ事情が道具の版ごとに違う言い方で出ます。結果が合わないときは版番号も入れてみます。
  • 直す命令を貼る前に、その命令が何を捨てるかを確かめます。取り消せないものが混ざっています。

よくある質問

Q. エラー文句を訳さないのはなぜですか。

検索するものだからです。道具は英語で出力し、訳した文句では何も見つかりません。言語に合わせるのは意味と対処だけです。

Q. 手元の画面と少し違います。

道具は版ごとに言い方を変えます。自分のパスや名前を消して残る骨格が同じなら同じエラーです。版が違うときは版番号も検索に入れます。

Q. 直す命令をそのまま実行してよいですか。

何を捨てるかを先に見ます。git reset --hard、強制プッシュ、docker system prune は戻せないものを消します — 該当する箇所には書いてあります。

Q. ここに無いエラーはどう探しますか。

文句から自分のパス・名前・数字を消し、残った部分だけを検索します。その残りが道具の作者が書いた文で、それで探すと結果が合います。