Claude Media
claude-code-actionのtsconfig.jsonクラッシュ — Bunの内部バグと回避策

claude-code-actionのtsconfig.jsonクラッシュ — Bunの内部バグと回避策

claude-code-actionが「directory mismatch for tsconfig.json」で落ちる問題の原因は最低2つあり、片方は未解決のBun本体のバグです。見分け方と回避策をまとめました。

anthropics/claude-code-action@v1をGitHub Actionsで使っていると、Claudeが1文字も応答する前にexit code 1でジョブが落ち、ログにInternal error: directory mismatch for directory ".../tsconfig.json", fd Nという一行が残ることがあります。原因は少なくとも2系統に分かれ、片方はすでに修正済み、もう片方はBunランタイム本体の未解決バグです。本記事では両方の見分け方と、確認されている回避策を扱います。

何が起きているのか — エラーの実体

このエラーはBunランタイムのファイルディスクリプタ(fd)管理内部で、tsconfig.jsonをシンボリックリンク経由のパスで開いたときに、正規化後のパスと突き合わせがずれて発生します。エラー文には「You don't need to do anything, but this indicates a bug」とあり、Bun側もユーザー操作の問題ではないとしています。

症状の重さは一定ではありません。一部のワークフローではこのメッセージがpostステップのクリーンアップ時に無害な警告として流れるだけで、実行自体は成功します。一方で、Claude CodeのSDK初期化の直前でこのエラーが出ると、new Anthropic({ apiKey, ... })の呼び出しに進む前にBunプロセスがexit code 1で終了し、Claudeが一度もAPIを呼ばずにジョブが失敗します。

SDK execution error: Error: Claude Code process exited with code 1
Internal error: directory mismatch for directory "/home/runner/work/_actions/anthropics/claude-code-action/v1/tsconfig.json", fd 4.
You don't need to do anything, but this indicates a bug.

原因は少なくとも2系統ある

claude-code-action#1205として2026年4月10日に報告されたこのクラッシュは、調査が進むにつれて単一の原因ではないことが分かってきました。

1. 機密パスがシンボリックリンクの場合(修正済み)

claude-code-action#1220の報告者corygabrielsenは、ログを精査した結果、tsconfig.jsonのエラーが出るに別のエラーが出ていることに気づきました。

Restoring .claude, .mcp.json, .claude.json, .gitmodules, .ripgreprc, CLAUDE.md, CLAUDE.local.md, .husky from origin/master (PR head is untrusted)
##[error]Action failed with error: ENOENT: no such file or directory, symlink

原因はaction側のrestore-config.tsにありました。actionはPRの機密パス(CLAUDE.md.claude.mcp.json.claude.json.gitmodules.ripgreprc.huskyなど)を.claude-pr/へスナップショットします。このときcpSyncが既定のdereference: falseでシンボリックリンクをそのまま再現しようとし、宛先の親ディレクトリがまだ存在しないためsymlink()ENOENTで失敗します。Bunのfdテーブルに残った不整合は、次のBun呼び出しでtsconfig.jsonのエラーとして表面化します。

この経路はPR #1186dereference: trueを追加し、2026年5月14日にマージされて解消しています。CLAUDE.mdなどをシンボリックリンクで運用しているリポジトリは、この日付以降のバージョンを使っていれば対象外です。

ls -la CLAUDE.md .claude .mcp.json .claude.json .husky 2>/dev/null

出力に->が含まれるパスがあれば、症状の一次要因はここにあった可能性があります。

2. Bun本体の未解決バグ(現在も残る)

もう一方の原因は根が深く、claude-code-action側では完全には塞げていません。エラーを引き起こしていたのは、Bunに--tsconfig-overrideフラグを渡す挙動そのものでした。上流のoven-sh/bun#22023は2025年8月21日に報告されて以来、コメント4件のまま動きの乏しいissueです。

claude-code-action側はこの1年で3段階の対策を打っています。

  1. PR #1239(2026年4月21日マージ): tsconfig.jsonのパスをrealpathで正規化してBunに渡す
  2. PR #1312(2026年5月14日マージ): 内蔵Bunを1.3.6から1.3.14へ引き上げ。Bun側のcpSyncシンボリックリンク回帰の修正取り込みが目的
  3. PR #1315(2026年6月9日マージ): --tsconfig-overrideフラグ自体を3箇所のbun run呼び出しから削除

3番目の対策がマージされた同じ日に、claude-code-action#1205はクローズされました。ただし、これは「このissueの再現手順では直った」という判断であり、症状そのものが根絶したわけではありません。関連issueのclaude-code-action#1295とclaude-code-action#1568は、いずれも開いたままです。

それでも再現が続く理由

--tsconfig-overrideを渡さなくなった後もクラッシュは報告され続けています。claude-code-action#1568の報告者は、actionがバンドルしているスクリプトに「このバグを避けるためのコメント」とフラグ削除が既に入っている点を確認した上で、それでも起きるのは「action自身のBunランタイム内部で、別だが関連するコードパスが同じ根本バグを引いているから」だと指摘しています。

2026年8月14日には、noctua84がバージョンを跨いだ再現マトリクスを共有しました。v1.0.111では安定して成功する一方、v1.0.161・v1.0.165など後続バージョンではクラッシュが再現し、同一SHAピン留めでも成功と失敗が入れ替わる非決定的な挙動だったと報告しています。ここにPR #1496(2026年7月13日マージ)が絡みます。この変更で、Claude Agent SDKがsubtype: "success"かつis_error: trueを返すケースを失敗として扱うようになりました。変更前はBunのバグで実質何も実行されていなくても緑のチェックが付くことがあり、変更後はその隠れた失敗が表に出るようになった、という副作用も報告されています。

2026年9月16日には、Carlhorst3443が現行の@v1(2026年9月15日付コミット)での再現報告を追加しました。pull_requestissue_commentの両イベント、3種類の異なるworkflowファイルのいずれでも、10回中10回同一のクラッシュが起きたという内容です。非決定的だった以前の報告とは対照的に、この報告では100%再現という結果でした。

今すぐ確認できること

症状疑う原因対処
ENOENT: no such file or directory, symlinkが先に出る疑う原因CLAUDE.md等がシンボリックリンク対処PR #1186マージ後(2026-05-14以降)のバージョンを使う。シンボリックリンクを外すのも回避策
symlinkなしでもtsconfig.jsonエラーが出る疑う原因Bun本体の未解決バグ(oven-sh/bun#22023)対処既知の安定バージョンにSHAピン留め。path_to_bun_executableで自前のBunバイナリを指定する方法もある
緑のチェックなのに実際は何も実行されていない疑う原因is_error: truesubtype: successに隠れている(PR #1496で2026-07-13以降は失敗扱いに変更済み)対処2026-07-13以降のバージョンを使っていれば発生しない

claude-code-actionのFAQは、Nix/NixOSやカスタムコンテナ向けにpath_to_bun_executableで自前のBunバイナリを指定できると案内しています。

- uses: anthropics/claude-code-action@v1
  with:
    anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
    path_to_bun_executable: "/path/to/custom/bun"

FAQには「特定バージョンの問題をデバッグする用途」とも明記されており、この症状の切り分けにも使える構成です。ただし公式ドキュメントはこの入力をこの特定バグの修正手段として案内しているわけではなく、あくまで自動インストールを迂回する汎用の脱出口である点は区別しておく必要があります。

一方、claude-code-action#1568でsimon-lowesが報告した「show_full_output: trueを設定すると5回中5回クラッシュを避けられた」という観察は、本人も「偶然でないか確認するためオン・オフを切り替えて試した」と述べる段階のデータです。翌日のCarlhorst3443の再現報告でも「まだ試していない」とされており、複数の環境で再現性が確認されたわけではありません。公開リポジトリでは実行結果ログが丸ごと世に出るリスクもあるため、これを常設の回避策として組み込む前に、自分の環境で同様の相関が出るかを確かめる段階の情報として扱うのが妥当です。

Bunを買収した後も、Bun本体のバグは残っている

Anthropicは2025年12月3日にBunを買収しました。買収後もBunはオープンソース・MITライセンスのまま外部提供が続いていますが、この記事で扱ったoven-sh/bun#22023は買収発表より前の2025年8月21日に報告されたまま、closedにはなっていません。claude-code-action側の3回の対策(realpath化・Bunバージョン更新・フラグ削除)は、いずれもaction側からBunの挙動を回避する形の対症療法であり、fdトラッキングの不整合自体を修正したわけではないという見方もできます。

claude-code-actionでは今回のtsconfig.jsonの一件が初めての不安定性報告ではありません。v2.1.227でも、allowed_non_write_users設定時にBashコマンドが全滅する別種の不具合が報告・修正されており、GitHub Actions経由の運用ではaction固有の落とし穴に複数回当たっている状況です。GitHub Actionsへの組み込み全体の設計はClaude CodeをGitHub Actionsに組み込むで扱っています。

まとめ

claude-code-actionが起動直後にexit code 1で落ち、ログにdirectory mismatch for directory .../tsconfig.jsonと出る場合、まずCLAUDE.md等の機密パスがシンボリックリンクになっていないかを確認します。該当すれば2026年5月14日以降のバージョンで解消済みです。シンボリックリンクが無いのに再現する場合は、Bun本体の未解決バグ(oven-sh/bun#22023)が原因である可能性が高く、action側の3回の修正では根絶していません。既知の安定バージョンへのピン留めが最も確実な回避策で、path_to_bun_executableによる自前Bunの指定も選択肢に入ります。show_full_output: trueの効果は、まだ限られた報告件数の観察にとどまります。

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