minorotherverifiedfirsthand
ブラウザのページ翻訳が自作Reactアプリを落としていた
ブラウザのページ翻訳(日本語)を有効にしたまま自作のReactアプリを使うと、画面の切り替えで`NotFoundError`が出てアプリが落ちた。しかもそのエラー表示まで機械翻訳されていた。
原因
ページ翻訳は裸のテキストノードを<font>要素に置き換える。Reactは自分が作ったはずのテキストノードを前提にinsertBeforeやremoveChildを呼ぶため、ノードが見つからずNotFoundErrorになる(react#11538)。
結果
条件によって表示が切り替わる箇所でアプリがクラッシュした。別の日には、GitHubの設定画面の権限検索が翻訳ONのときだけ候補を1件も出さなかった。
対策
条件で切り替わるアイコンの隣にあるテキストは<span>で包む。恒久策として、insertBeforeとremoveChildの失敗を穏やかに処理するガード部品を入れる。設定画面を案内するときは、最初に翻訳をOFF(原文表示)にしてもらい、項目名は英語で伝える。
何が起きたか
自作のReactアプリが、画面を切り替えた瞬間にクラッシュした。出てきたのはNotFoundError。
コードを見直しても、そんなノードを消した覚えはない。
犯人はアプリの外にいた。使う側が、ブラウザのページ翻訳(日本語)を常にONにしていたのだ。 このクラッシュは2026年7月19日に修正された。
現場の混乱
混乱を深めたのは、エラーの画面そのものだった。Reactのエラーオーバーレイも、 ページの一部としてしっかり日本語に翻訳されて表示されていた。スクリーンショットに写った 日本語のエラーは、エラーの原文ではなく機械翻訳だった。調べる側からすると、 どこまでが本物のメッセージなのかがまず分からない。
同じ仕組みは、自分のアプリの外でも牙をむいた。2026年9月28日、GitHubでfine-grained tokenを 作る画面の「Add permissions」検索が、翻訳ONのままだと候補を1件も返さなかった。 表示は「利用可能なアイテムはありません」。権限が存在しないのかと思わせる表示だが、 原文表示に戻したら普通に通った。
原因
ブラウザのページ翻訳は、ページ内の裸のテキストノードを<font>要素で置き換えて訳文を入れる。
ところがReactは、自分が描画したテキストノードがそのままDOMに残っている前提で動く。
条件によって要素を差し替えるとき、Reactは元のノードを基準にinsertBeforeやremoveChildを
呼ぶ。そのノードはもう翻訳機能に差し替えられているので、DOMは「そんなノードは無い」と
NotFoundErrorを投げる。Reactの既知の問題(react#11538)で、React製のアプリなら
どれでも同じことが起こりうる。
対策
まず、条件で切り替わるアイコンの隣にある条件付きテキストを<span>で包んだ。
テキストが要素の中に収まっていれば、翻訳機能が中身を書き換えても、Reactが扱う
ノードの位置関係は崩れない。
恒久策として、insertBeforeとremoveChildが失敗しても例外で落とさず穏やかに処理する
ガード部品を入れた。新しく作るReactアプリにも同じパターンを入れる方針にしている。
運用面では二つ決めた。日本語で届いたエラーのスクリーンショットは、まず機械翻訳を疑う。 GitHubなどの設定画面を案内するときは、最初に翻訳をOFF(原文表示)にしてもらい、 項目名は英語のまま伝える。
出典
- 運営者自身が起こした事故の一次記録です。外部に公開された元記事はありません。