Claude Media
「Cannot read this as an image」の原因と128MB上限 — Claude Code

「Cannot read this as an image」の原因と128MB上限 — Claude Code

Readで画像を開いたときの「pipe or a device」エラーは、通常ファイルではない入力が128MBを超えて流れ続けたときに出ます。通常ファイル側の上限との違いと、一時ファイルを挟む直し方をまとめました。

Cannot read this as an image: <path> is a pipe or a device, not a regular file, and it sent more than 128MB without ending. は、Readツールが画像として開こうとしたパスが、普通のファイルではなくパイプかデバイスで、128MBを超えても終わらなかったときのエラーです。

画像が大きすぎる系のエラーと思われがちですが、原因は寸法でも圧縮率でもありません。読み込み元の種類です。直し方は「通常の画像ファイルに書き出してから読ませる」の1点に絞れます。

2つの文言は同じ節にあり、上限はどちらも128MB

Claude Codeのエラー一覧には、画像のサイズに関する文言が2つ並んでいます。どちらも同じ「File is too large to read as an image」の節に入っています。

くらべる

通常ファイルの場合と、パイプ・デバイスの場合

File is too large

通常ファイル

画像ファイルが128MBを超えていると、何も読まれずに File is too large to read as an image (the limit is 128MB): <path>. が返ります。末尾には「画像なら縮小するか、小さいコピーを書き出してから読む」という趣旨の指示が付きます。

Cannot read this as an image

パイプ・デバイス

パスが通常ファイルではない場合は、128MBを超えて届いた時点でReadが読み込みを打ち切り、Cannot read this as an image で始まる文言を返します。「終わりなく送られてきた」という点が通常ファイルとの違いです。

エラー一覧は、どちらもClaudeにツール結果として返ると説明しています。つまりセッション自体が落ちるのではなく、Claudeがエラー文を読んで次の手を選ぶ段階に戻ります。

ここで注意したいのは、128MBが「Claudeが見る画像の上限」ではないことです。Claude Codeは大きな画像を、モデルの画像サイズ上限に収まるよう自動で縮小して送ります。128MBは、その前段でReadが1つの画像ソースから読み込む量の上限です。画像の寸法やAPIへ送る前提の上限が原因のエラーは別物で、「Image was too large」の原因と対処に切り分けがあります。

なぜパイプやデバイスだけ別の文言になるのか

通常ファイルなら、開く前にファイルサイズを調べられます。128MBを超えていれば、中身を読む前に断れます。

パイプやデバイスは事情が違います。手元のmacOSで stat を実行すると、通常ファイルは実際のバイト数を返し、名前付きパイプ(FIFO)は0を返しました。

printf 'x' > a.png
mkfifo p.png
stat -f '%HT %z %N' a.png p.png /dev/null

出力は次のようになります(macOSでの結果です。Linuxでは stat -c '%F %s %n' を使います)。

Regular File 1 a.png
Fifo File 0 p.png
Character Device 0 /dev/null

FIFOやキャラクタデバイスの「サイズ」は、事前に分かる値ではありません。書き込む側が何バイト流すかは、実際に読んでみるまで決まらないからです。そのためReadは、サイズの事前確認ではなく、読みながら量を数えて128MBで止める方式になっていると考えられます。errors.mdの文言にも「128MB超が届いても終わらなかった」とあり、数えながら読む挙動と合っています。

ここから先は推測ですが、/dev/zero のように終わりのないデバイスを画像名で渡すと、通常ファイルの事前チェックでは防げず、この打ち切りに頼ることになります。

どんな場面で出るのか

エラー一覧が挙げる条件は「パスがパイプかデバイスで、通常ファイルではない」ことだけです。この条件に当たる形を、シェルの基本知識から挙げます。

  • プロセス置換 <(...) で作った /dev/fd/N を、画像のパスとして渡した
  • mkfifo で作った名前付きパイプに、画像名(.png など)を付けて渡した
  • 画像名のシンボリックリンクが、デバイスファイルを指している

リンクの先が通常ファイルかどうかは、ls -lL や stat -L で確かめられます。Claude Codeのchangelogには、v2.1.302で「画像ファイルや、画像名のパイプ・デバイスを丸ごとメモリに載せていた問題を修正し、128MBを超える画像ソースは拒否する」と書かれています。changelogが「画像名のパイプやデバイス」と書いているとおり、名前が画像でも中身がパイプやデバイスなら、ここで止まります。

v2.1.302より前は、この上限自体がありませんでした。巨大なファイルや終わりのない入力を渡すと、メモリを食い続ける可能性があったということです。エラーが出るのは、上限を設けた側の挙動です。

直し方: 通常ファイルへ書き出してから読む

エラー一覧の対処は3つに整理されています。

  1. Claudeがエラー文に従い、縮小や小さいコピーの読み直しまで進んだなら、何もしない
  2. Claudeがエラーで止まったなら、128MB未満のコピーを自分で書き出し、そのファイルを指す
  3. パスがパイプやデバイスだったなら、通常の画像ファイルを指し直す

パイプやデバイスの場合は3が本筋です。流れてくるデータを、一度ディスク上の通常ファイルに受け止めます。

手順

一時ファイルを挟んで読ませる

  1. 1

    流れてくる出力を通常ファイルに保存する

    出力元のコマンドの標準出力を、> /tmp/shot.png のようにリダイレクトします。プロセス置換で渡していたものは、このリダイレクトに置き換えます。

  2. 2

    種別とサイズを確かめる

    stat で通常ファイル(Regular File)であることと、バイト数を確かめます。画像として壊れていないかは file で見ます。

  3. 3

    そのパスをClaudeに渡す

    保存した通常ファイルのパスを指して「この画像を見て」と伝えます。128MB未満であれば、Readは通常の画像として開きます。

終わりのない入力が混ざる場合は、書き出す量にも上限をかけておくと、ディスクを食いつぶしません。

# 例: 出力元コマンドは各自の環境に置き換える
your-capture-command | head -c 100000000 > /tmp/shot.png
stat -f '%HT %z %N' /tmp/shot.png
file -b /tmp/shot.png

head -c 100000000 は先頭の約100MBだけを保存します。途中で切れた画像は壊れるので、上限に達した場合は出力元の設定(解像度や形式)を見直すほうが筋です。file が画像の形式を答えれば、中身は読める状態です。

画像のサイズ自体が大きいなら、小さいコピーを作る

通常ファイルの側で File is too large が出た場合は、書き出し直しではなく縮小が本筋です。macOSなら標準の sips で長辺を指定して縮小できます。

sips -Z 4000 big.png --out small.png
stat -f '%z %N' small.png

-Z 4000 は縦横比を保ったまま、長辺を4000pxに収めます。元ファイルは上書きされません。128MBを超える画像は、そもそも非常に大きな解像度か、圧縮の弱い形式のものです。長辺を縮めれば、容量は大きく下がります。

縮めすぎて文字が読めなくなる場合は、全体を縮小するのではなく、読みたい領域だけを切り出す手があります。tools-referenceには、細部が読めないときは範囲を切り出してから読ませるよう頼む案内があります。切り出しは、ImageMagickのようなツールをBash経由で呼ぶ例が挙げられています。

再発させない: CLAUDE.mdに書いておく規約

Claudeが毎回パイプやデバイスを画像として開こうとするなら、読み込み方の規約をプロジェクトに置いておけます。次はそのまま貼れる形の例です。

## 画像の読み込み
- 画像はパイプ・プロセス置換(`<(...)`)・/dev/fd 配下から直接読まない。
- 生成や取得をした画像は、まず通常ファイルとして保存してから Read する。
- 128MB を超えるファイルは Read せず、縮小コピー(長辺 4000px 目安)を作ってから読む。
- 保存したら `stat` で通常ファイルであることとサイズを確認する。

この規約は、エラー一覧の対処(通常ファイルを指し直す・128MB未満のコピーを書き出す)を、毎回言わなくて済む形にしたものです。数値の4000pxは例で、公式の推奨値ではありません。

似た画像系エラーとの見分け方

画面に出た文言で、どの上限に当たったかが分かります。

画面の文言原因主な対処
Cannot read this as an image ... pipe or a device原因通常ファイルではない入力が128MBを超えた主な対処通常ファイルに書き出して指し直す
File is too large to read as an image (the limit is 128MB)原因通常の画像ファイルが128MB超主な対処縮小、または小さいコピーを書き出す
Image was too large原因画像の寸法かサイズがAPIの上限超主な対処長辺を縮めて貼り直す
Unable to resize image原因Claude Code側の読み取りや縮小に失敗主な対処PNG/JPEG/GIF/WebPへ変換

上の2行は「Readが画像ソースを受け取る段階」の上限で、下の2行は「受け取った画像をAPIへ送る段階」の問題です。段階が違うので、直し方も違います。後者は「Unable to resize image」が出る原因と対処法に文言別の切り分けがあります。会話全体が大きくなって出る場合はClaude Codeの「Request too large」が出たときの対処法の領分です。エラー全般の入口はClaude Codeでよくあるエラー10選にまとまっています。

貼り付けと@指定はこのエラーの対象か

エラー一覧が示す入口はReadツールです。クリップボードからの画像貼り付けで出る失敗は、別の経路になります。たとえばWSL2での貼り付けはClaude CodeのWSL2で画像貼り付けができない原因と回避策、Terminal.appでの貼り付けはClaude CodeのTerminal.appで画像貼り付けが効かない原因とOption+-の中断が扱っています。

また、@ でメンションしたファイルをReadが拒否した場合、Claudeにはパスだけが渡り、中身は渡らないとtools-referenceにあります。パイプやデバイスを @ で指しても、中身が読まれるわけではありません。

版ごとの違い

バージョン画像ソースの扱い
v2.1.302より前画像ソースの扱い画像ファイルや画像名のパイプ・デバイスを、サイズによらずメモリへ読み込んでいた
v2.1.302以降画像ソースの扱い128MBを超える画像ソースは拒否し、エラーを返す

v2.1.302のリリースノートは、このほかの変更もまとめています。上限が入った後は、巨大な入力でもメモリが無制限に膨らむ代わりに、このエラーでClaudeに状況が伝わります。

まとめ

Cannot read this as an image は、画像の中身ではなく、読み込み元がパイプかデバイスだったことに由来します。直し方は、通常の画像ファイルに書き出し、stat で種別とサイズを確かめてから読ませることです。通常ファイルで128MBを超える場合は、縮小したコピーを作ります。

プロセス置換や名前付きパイプで画像を渡す運用は、CLAUDE.mdに「保存してから読む」と書いておけば、同じ止まり方を繰り返さずに済みます。

この記事を共有:XはてブLinkedIn