Claude CodeのMessage too largeなど、セッション間送信エラー3種の対処
セッション間メッセージで出るMessage too large・Too many messages・Refusing to sendの意味と対処を整理。ファイル渡しで解ける拒否と、解けない拒否の違いも示します。
別のセッションにメッセージを送らせたら、Message too large for cross-session deliveryと返ってきた。そんなときは、送信側のClaude Codeが送信そのものを止めています。受信側のセッションには何も届いていません。
セッション間メッセージの送信拒否は3種類あります。上限超過のMessage too large、短時間に送りすぎたToo many messages、宛先ソケットの検査に落ちたRefusing to sendです。前の2つはメッセージの出し方を変えれば解けますが、3つ目は送り方を変えても解けません。この違いが切り分けの要です。
機能の使い方は@メンションでセッション間の連携を制御する記事にあります。本稿は、送信時に出るエラー文言から原因を引く側に絞ります。
3つの拒否を最初に見分ける
どの拒否も、表示先は送信側セッションのツール結果です。ターミナルのバナーには出ません。Claudeが「送れませんでした」と報告しなければ、利用者が気づかないこともあります。
| ツール結果の文言 | 起きていること | 送り方で解けるか |
|---|---|---|
Message too large for cross-session delivery | 起きていること本文が上限を超えた | 送り方で解けるか解ける(短縮・ファイル渡し・分割) |
Too many messages to this session just now | 起きていること送信の連打が受信側の上限に達した | 送り方で解けるか解ける(1通にまとめる・少し待つ) |
Refusing to send: reply target is a symlink | 起きていること宛先ソケットの場所にシンボリックリンクがある | 送り方で解けるか解けない(送らないのが正しい動作) |
Refusing to send: cannot vet reply target | 起きていること宛先のパスを調べられなかった | 送り方で解けるか解けない(検査自体が通らない) |
3種のどれも、拒否された時点で送信は行われていません。同じ文面を再送しても、条件が変わらなければ同じ拒否になります。
Message too largeは上限1,048,576文字の超過
文言は宛先名と2つの数字を含みます。
Failed to send to api-worker: Message too large for cross-session delivery: the serialized message is 1,203,844 characters and the limit is 1,048,576. Shorten the message text — put bulk content in a file the recipient can read rather than in the message — or split it into smaller messages.上限は1,048,576文字で、1024×1024と同じ値です。比べられるのは本文の文字数ではなく、送信用に直列化(シリアライズ)した後のメッセージです。エラー文のthe serialized message isも、直列化後の文字数を指します。
エラー文にも対処が書かれています。バルク(大量)の内容はメッセージに入れず、受信側が読めるファイルに置く。それでも長ければ複数の短いメッセージに分ける。この2択です。
典型的に踏むのは、テストログやビルド出力、差分の全文を「そのまま伝えて」と頼んだときです。ファイル渡しにすると、次の形になります。
@api-worker にテスト失敗の詳細を伝えて。ログ全文は ./tmp/test-failure.log に
書き出して、メッセージにはそのパスと失敗した上位5件の要約だけを入れてファイル渡しが使えるのは、送信側と受信側が同じマシン上で同じファイルを読める場合です。セッション間メッセージの宛先は同一マシンのセッションなので、この前提は通常満たされます。メッセージに@付きのパスを書いても、受信側ではただのテキストとして届き、ファイルは添付されません。受信側のClaudeが自分のツールでパスを開き、そのときはそのセッション自身の権限設定が適用されます。
v2.1.235より前は、この上限超過が「送信済み」と報告されていました。受信側が未読のまま捨てていたため、古いバージョンでは「送れたのに反応がない」という形で現れます。
Too many messagesは連打が上限に達したサイン
2つ目は、短い間に同じセッションへ送りすぎたときの拒否です。
Failed to send to api-worker: Too many messages to this session just now: 30 were sent recently and more would be dropped by its rate limit, so this one was not sent. Batch what remains into one message, or wait a little before sending more.文中の30は、宛先の受信箱が受け付ける直近の送信数です。その期間の長さは、ドキュメントに記載がありません。「30通を超えたら必ず拒否」ではなく、「直近30通に達したので次を送らなかった」という報告と読むのが正確です。
対処は、残りの内容を1通にまとめるか、少し待つかです。ドキュメントは「たいていは何もしなくてよい」としています。Claudeがこの文言を読み、残りをまとめて送るか待つからです。
自分で連打を引き起こしたときは、まとめを頼みます。たとえば、10個のサブタスクの完了を1つずつ別のセッションに通知させているなら、「全部終わったら1通で報告して」と指示を変えます。
v2.1.236より前は、この拒否も「送信済み」と報告され、受信側が未読で捨てていました。
Refusing to sendは送り方では解けない
3つ目は性質が違います。送信前に、Claude Codeは宛先セッションの受信ソケットが「メッセージの宛先として想定したもの」であるかを検査します。検査に落ちると送信を拒否します。
Failed to send to api-worker: Refusing to send: reply target is a symlinkRefusing to send:の後ろの文が、落ちた検査を示します。
reply target is a symlink: 宛先セッションのソケットがあるパスに、シンボリックリンクがあります。リンクはメッセージを、宛先セッションが作っていないエンドポイントへ向けられるため、Claude Codeはそこを通して配信しませんcannot vet reply target: 宛先のパスを調べられませんでした。たとえば読み取りが権限エラーで失敗した場合です
ここでファイル渡しやバッチ化に切り替えても意味はありません。サイズも件数も原因ではないからです。ドキュメントの案内は「たいていは何もしなくてよい」です。検査は、メッセージが想定外のエンドポイントに届くのを防ぐためのもので、拒否された時点で何も送られていません。
reply target is a symlinkが同じセッション相手に繰り返し出るときだけ、調査が要ります。そのセッションの/statusにあるPeer addressの行がソケットのパスです。そのパスにリンクを置いたものが何か(自作スクリプトやsync系ツールなど)を探します。
送信は通ったのに破棄される4つ目のケース
3種の拒否に加えて、似た文言がもう1つあります。送信側は送れたつもりでも、受信側の受信箱が読む前に捨てた場合です。
Cross-session message was dropped at the recipient session's inbox (recipient: uds:/tmp/cc-socks/13605.sock) and not delivered — its queue of undelivered peer messages was full. Claude was told not to resend right away.ダッシュの後ろに理由が付きます。
| 理由の文言 | 意味 |
|---|---|
its queue of undelivered peer messages was full | 意味受信側に他セッションからの未配信が溜まりすぎている |
you sent faster than that session accepts | 意味1つの送信元からの到着が速すぎる |
it repeated your previous message | 意味直前に送った内容と同一だった |
a relay loop between sessions was cut | 意味セッション同士が送り合う連鎖が長すぎるか、受信側を何度も通った |
1行が複数のメッセージ分をまとめることもあり、その場合はCross-session messages (12) were droppedのように複数形で始まります。recipient:のアドレスがどのセッションかは、各セッションの/statusにあるPeer addressと見比べて突き合わせます。受信側は、未読の受信キューに最大50通までしか積みません。
最初の3つはToo many messagesと同じ種類の現象です。違いは、拒否が送信側で行われるか、受信側で行われるかにあります。受信側が捨てたメッセージは届いていないものとして扱い、重要な内容は1通にまとめて後から送ります。Claude Codeも同じ指示をClaudeに出します。
relay loopのときは、どちらかのセッションに自分でプロンプトを打ちます。利用者の入力に応じてClaudeが送るメッセージは、新しい連鎖として数えられます。
拒否も破棄もないのに届かないとき
ここまでのエラー文言が出ていないのに反応がないなら、受信側の設定が原因のことがあります。
受信側のcrossSessionInboundがholdなら、メッセージは通知だけ表示されて配達されません。refuseなら、メッセージは配達されずに捨てられます。設定が何も効いていない場合は、両セッションの権限モードで決まります。
受信側がプロンプトで確認するモードなら、送信側も確認モードである限り配達されます。どちらかが権限確認を飛ばすモード(bypass)で、もう一方が同じ種類でないときは、承認待ちで止まります。承認待ちのダイアログは、dialogExpiryの期限(既定5分)を過ぎると閉じ、メッセージは捨てられます。VS Code拡張やDesktopアプリのセッションにはこのダイアログが出ません。止まったメッセージは期限まで保持されるだけです。
届いたかどうかは、受信側の画面でも確かめられます。届いたメッセージは› Message from @api-worker: …の形で、送信元の名前と本文の1行目だけの薄いプレビューとして会話に残ります。全文はCtrl+Oのトランスクリプト表示で読めます。承認待ちで保持されるメッセージは最大100通で、超えると古いものから捨てられます。
宛先が見つからないときは、送信側で/list-agents(別名/peers)を実行します。コマンド自体が認識されなければ、そのセッションにはセッション間メッセージ機能がありません。実行できるのに届かないなら、権限のdenyルールでSendMessageが外れていないか、宛先のセッションがofflineやcan't receive cross-session messagesの表示になっていないかを見ます。後者の宛先では、SendMessageのツール結果がNot sentで始まります。
症状から原因を引く早見
エラー文言が見えないまま「届かない」と相談されたときは、次の順で当たります。
届かないときの切り分け順
- 1
送信側のツール結果を読む
Failed to sendやdroppedの文言があれば、上の4種のどれかです。 - 2
本文の大きさと送信回数を疑う
ログや差分の全文を送っていないか。短時間に何通も送っていないか。
- 3
リンクが原因かを見る
Refusing to sendなら、/statusのPeer addressのパスを確かめます。 - 4
バージョンを確かめる
エラー文言が何も出ないなら、古いバージョンで「送信済み」と誤報されている可能性があります。
バージョンの目安は、上限超過がv2.1.235、連打拒否がv2.1.236、受信箱の破棄報告がv2.1.238です。これより前のバージョンでは、拒否や破棄が送信側に伝わりません。claude --versionで確認し、古ければ更新します。
運用で拒否を減らすには
大きな内容を渡す場面が多いなら、CLAUDE.mdに送り方の規約を書いておく手があります。記述例は次のとおりです。
## セッション間メッセージの送り方
- 本文は短く保つ。ログ・差分・生成物は ./tmp/ にファイルで書き出し、パスと要約だけ送る
- 同じ宛先に連続で送らない。作業が終わった時点で1通にまとめて報告するこれは書き方の例であり、必ず守られる保証はありません。効果を見るなら、規約を入れた後にMessage too largeやdroppedが出なくなるかを、送信側のツール結果で確かめます。
Windowsのネイティブ環境でセッション間メッセージが応答しなくなる不具合は、送信エラーとは別の問題です。Windowsでクロスセッションメッセージが応答しなくなる不具合が扱っています。受信箱ソケットへフックから直接書き込む方法はソケット環境変数の記事にあります。
まとめ
Message too largeとToo many messagesは、送り方を変えれば解ける拒否です。前者はファイルに逃がすか分割する、後者は1通にまとめるか待つ。Refusing to sendは送り方と関係がなく、リンクや権限といった宛先側の状態の問題です。
見分けるときは、まず送信側のツール結果を読みます。拒否の文言が出ていれば原因は特定でき、何も出ないのに届かないなら、バージョンの古さと受信側での破棄を疑う順になります。エラー全般の探し方はClaudeエラーメッセージ一覧も参照してください。