「can't read the keyboard here」が出るClaude Codeの原因と直し方
-pなしでclaudeを起動したのに標準入力が端末でないと出るエラー。WindowsとmacOS・Linuxで挙動が違う理由と、-pへの切り替え方をまとめます。
Claude Code can't read the keyboard here: stdin is not a terminal は、-p を付けずに claude を起動したのに、標準入力(stdin)が端末につながっていないときに出るエラーです。直し方は2つだけです。端末で直接 claude を実行するか、-p を付けて非対話モードに切り替えます。
このエラーは何を言っているのか
claude を -p なしで起動すると、対話セッションが始まります。対話セッションはキー入力を端末から読むので、stdinが端末でなければ進めません。
stdinが端末でなくなる典型は次の3つです。
- パイプで渡している(
type notes.md | claude) - ファイルからリダイレクトしている(
claude < prompt.txt) claudeを起動したプログラムが独自の入力ストリームを用意している
メッセージの括弧内にある「piped, redirected, or supplied by the program that launched claude」は、この3つをそのまま指しています。
WindowsとmacOS・Linuxで挙動が分かれる
同じ状況でも、OSによって結果が違います。
| OS | stdinが端末でないとき |
|---|---|
| Windows | stdinが端末でないときstderrにメッセージを出し、終了コード1で終わる。対話画面は始まらない |
| macOS / Linux | stdinが端末でないとき/dev/tty からキー入力を読み、セッションを始める。パイプされた文字列は最初のプロンプトになる |
macOS / Linuxでは、パイプ経由でも普通に起動できます。このエラーが出るのは /dev/tty を開けなかったときだけで、その場合は1行目がWindows版の文言ではなく /dev/tty に言及する形に変わります。
macOS / Linuxでどちらに当たったかは、メッセージの1行目で見分けます。「stdin is not a terminal」で始まり末尾にWindowsの文言があればWindowsの挙動、/dev/tty の名前が入っていれば制御端末を開けなかった場合です。
つまり、Windowsで出たなら「パイプやリダイレクトを使った」時点で原因はほぼ確定です。macOS / Linuxで出たなら、そのプロセスに制御端末がない状況を疑うことになります。
Windowsで出るメッセージの全文
Windowsでは3行のメッセージがstderrに出ます。
Claude Code can't read the keyboard here: stdin is not a terminal (it is piped, redirected, or supplied by the program that launched claude), and on Windows it can't fall back to the console for input yet.
Run claude directly in Windows Terminal, PowerShell, or Command Prompt, without piping or redirecting its input.
To send text as a prompt and print the reply instead, add -p; it also works with --continue and --resume <session-id> (for example: type notes.md | claude -p --continue).1行目が原因、2行目が対話で使う場合の直し方、3行目が -p に切り替える場合の直し方です。メッセージ自体が答えを書いているので、読み飛ばさないことが近道です。
切り分け: どちらの直し方を選ぶか
stdin が端末でないときの分かれ道
- Q人がキーボードで会話するつもりで起動したか?答えがいいえ答えがはい
スクリプトやツールから呼んでいるなら、対話画面は不要です。
-pを付けて、プロンプトを引数かstdinで渡します。 - Qパイプやリダイレクトを付けて起動していないか?答えが付けていない答えがはい
付けているなら外し、端末で
claudeだけを実行します。付けていないのに出るなら、起動元のプログラムが入力を肩代わりしています。次の確認へ進みます。
起動元のプログラムが入力ストリームを持っている
IDEの出力ペインやタスクランナーなど、本物の端末ではない場所から起動しています。IDEの統合ターミナルやWindows Terminalで実行し直します。
Flowのあとに、OSごとの最初の一手を足しておきます。
- Windows: パイプやリダイレクトを外して、PowerShellのコンソールかコマンドプロンプトで
claudeだけを実行します。それで起動するなら、原因は入力の加工です。 - macOS / Linux: 同じコマンドをSSH先やcronのような制御端末のない環境で動かしていないかを見ます。手元の端末で起動できるなら、環境側の問題です。
直し方1: 端末で直接実行する
対話セッションを使いたいなら、入力を加工せずに端末で実行します。実行場所は、WindowsならISEではなくPowerShellのコンソール、IDEなら出力ペインではなく統合ターミナルです。
claudeWindowsならWindows Terminal、PowerShell、コマンドプロンプトのいずれかです。パイプやリダイレクトは付けません。最初に読ませたい文章がある場合は、起動後に貼り付けるか、ファイルのパスをプロンプトに書いて読ませます。
直し方2: -pに切り替える
スクリプトから呼ぶなど、対話画面が要らない用途では -p を付けます。プロンプトは引数でもstdinでも渡せます。
claude -p "your question"
echo "your question" | claude -pWindowsのコマンドプロンプトで、ファイルの中身を渡す例は次のとおりです。メッセージ中の例と同じ形で、--continue と組み合わせています。
type notes.md | claude -p --continuePowerShellなら、type の代わりに Get-Content で同じ形になります。
Get-Content notes.md | claude -p --continueWindowsのスクリプトから呼ぶ場合、エラー時の終了コードは1です。%ERRORLEVEL%(コマンドプロンプト)や $LASTEXITCODE(PowerShell)で見られるので、-p に直す前にこの値で今回のエラーかどうかを絞れます。ただし1は他の失敗でも返るため、決め手はstderrのメッセージ本文です。
--continue は直近の会話の続き、--resume <session-id> は指定したセッションの続きです。どちらも -p と併用できます。この2つの使い分けはClaude Codeの/resumeコマンドで過去の会話を再開するで扱っています。
-p の基本(出力形式、--bare、セッションの続き方)はClaude Code -pモードでスクリプトやパイプラインを自動化する基本にまとまっています。
前段の出力を会話に流し込むとき
対話セッションに前段コマンドの出力を渡したくてパイプを使っているなら、本質的には「一度きりの質問」です。-p に置き換えると、Windowsでも同じスクリプトが動きます。
cat build-error.txt | claude -p 'concisely explain the root cause of this build error' > output.txt非対話モードのstdinは上限が10MBです。超えると明確なエラーと非ゼロの終了コードで止まるので、大きなログは、ファイルに書き出してパスをプロンプトに書く形にします。
-p を付けてもstdinが読めない場合があります。起動したプロセスが入力側を切り離しているときです。この場合、Claude Codeはstderrに警告を出し、コマンドラインのプロンプトだけで処理を続けます。v2.1.211より前のWindowsでは、セッションが落ちるか、何も出力せずに終了していました。つまり -p なら、読めないstdinで止まることはなく、止まるのは -p なしの場合です。
スクリプトに入れておくと便利なガード
同じスクリプトを人が手で叩く場合と、CIやタスクランナーから呼ぶ場合があるなら、stdinが端末かどうかで分岐できます。シェルの [ -t 0 ] は、stdinが端末のときに真になります。
if [ -t 0 ]; then
claude "$@" # 端末なら対話セッション
else
claude -p "$@" # パイプ・自動実行なら非対話
fiこれはClaude Codeの機能ではなく、シェル標準の判定です。PowerShellでは [Console]::IsInputRedirected が同じ役割を果たします。
似たエラーとの区別
stdinや -p まわりのエラーは文言が近く、取り違えやすい組み合わせです。
| 出力 | 状況 | 直し方 |
|---|---|---|
Claude Code can't read the keyboard here | 状況-p なしで、stdinが端末でない | 直し方端末で直接実行するか -p に切り替える |
Error: Input must be provided either through stdin or as a prompt argument when using --print | 状況stdoutがリダイレクトされた、または -p にプロンプトもstdinもない | 直し方プロンプトを引数かstdinで渡す |
Error: Input contained only whitespace. … | 状況-p に渡した内容が空白だけ | 直し方中身のある文字列を渡す。詳細は「contained only whitespace」エラーの対処 |
2行目は紛らわしい点があります。素の claude は、stdoutが端末でないとき(リダイレクト時、PowerShell ISEや一部のIDE出力ペイン)に非対話モードで動きます。そのため -p を付けていないのに、メッセージには --print と出ます。
今回のエラーは逆向きです。stdoutではなくstdinが端末でないことが引き金になっています。
v2.1.287より前との違い
v2.1.287より前のClaude Codeは、このメッセージを出さずに対話画面を始めようとしました。その結果、画面に何も出ないか、Raw mode is not supported を含むエラーで失敗していました。
手元のバージョンは claude --version で確かめられます。v2.1.287以降のWindowsなら、stdinが端末でないときは今回のメッセージで止まるので、画面に何も出ないまま固まる症状は別の原因が考えられます。ただしmacOS / Linuxでは /dev/tty を開ける限りセッションが始まるため、メッセージが出ないこと自体は正常です。
古いバージョンで Raw mode is not supported を見たなら、原因は同じ「stdinが端末でない」だった可能性があります。ただし、claude install の最中に出る Raw mode is not supported は別の話です。組織の管理設定による承認ダイアログがパイプ経由のインストールで出ようとして失敗するもので、v2.1.246より前の挙動として説明されています。この場合は、インストーラーを再実行すれば抜けられます。
Windowsのシェルで exit code 1 だけが返って出力がないという症状を調べているなら、Claude CodeがWindowsでexit code 1・出力なしになる原因と切り分けも参考になります。
つまずきやすい点
落とし穴
-pを付けたのにパイプ入力が会話に使われない
-p を付けると対話画面は出ず、返答を出力して終わります。画面上で追加の質問を重ねたい場合は、-p ではなく端末での対話が向いています。続きの質問は --continue で投げ直す形になります。
- macOS / Linuxで動いているスクリプトをWindowsに持ち込むと、動作が変わる場合があります。前者は
/dev/ttyに逃げて対話を始めますが、後者は止まります。パイプを使うスクリプトは、最初から-pにしておくとOS差を避けられます。 - 他のプログラムから
claudeを子プロセスとして起動する場合、そのプログラムがstdinを独自に用意していることがあります。起動方法を端末接続にするか、-pで呼ぶ設計にします。