Claude Codeが作業ディレクトリを見失う問題の原因と対処法
cdやworktree移動の後もClaude Codeが古い作業ディレクトリを引きずる現象と、環境変数CLAUDE_BASH_MAINTAIN_PROJECT_WORKING_DIRによる対処をGitHub issueの報告から見ます。
Claude Codeが作業ディレクトリを見失うとは何が起きるのか
Claude Codeが、実際にいるディレクトリとは違う場所にいると思い込んで動くことがあります。コマンドが失敗し、cdとlsを何度も繰り返してからようやく正しい場所にたどり着く、という報告がGitHub issue #1669に集まっています。issueは2025年6月5日に起票され、bug・area:core・oncallという3つのラベルが付いています。2026年8月にもコメントが付いており、クローズはされていません。
起票者は、この現象によってgitの強制リセット(git reset --hard)を誤ったディレクトリで実行してしまい、60時間分の作業を失ったと書いています。コメント欄には同様の被害報告が続きます。あるユーザーは、ビルド用のサブディレクトリを掃除するつもりが、Claude Codeがプロジェクト直下だと思い込んでファイルを一括削除したと報告しました。直前のコミットから変更が無かったため実害はなかったものの、破壊的な操作と組み合わさったときの危うさを示す例です。
別のユーザーは、存在しないパスへのcdと、存在しないファイルへのReadを何十回も繰り返す様子を記録しています。同じファイルへのアクセスを別のディレクトリから試み続け、ユーザーが手動で止めるまで収束しませんでした。もう一人のユーザーは、git mvでスクリプトをscripts/ディレクトリへ移したつもりが、Claudeが実はすでにscripts/の中で作業していたために直下に留まってしまった例を報告しています。pwdを実行するまで、本人もClaudeもこのズレに気づいていませんでした。
影響の大きさを訴える声も複数あります。あるユーザーはこの現象を「venvのsource忘れ、todoの検証不足と並ぶ上位3つの時間浪費」と表現し、別のユーザーは「ユーザーの時間だけでなく、支払っているトークンも無駄にする」と指摘しました。
なぜ起きるのか — 公式ドキュメントが示す手がかり
Anthropicはこのissueに直接原因を説明していませんが、公式ドキュメントの記述からは手がかりが読み取れます。ステータスラインのリファレンスは、workspace.project_dir(起動時のディレクトリ)がworkspace.current_dir(現在のディレクトリ)と「セッション中に作業ディレクトリが変われば異なることがある」と明記しています。つまり起動時の場所とセッション中の実際の場所がずれること自体は、公式にも想定済みの挙動です。
一部のユーザーはシェルの設定ファイルに原因を見つけています。あるコメントは、~/.profileからcd $HOMEの行を削除したところ問題が解消したと報告しました。シェルの起動スクリプトでcdを実行していると、Claude Codeの認識がずれやすくなるという指摘です。ただし別のユーザーはこの説明に反論し、「この問題は一般的にそれとは無関係で、Claudeは数秒前にした操作すら本当に忘れる」とコメントしています。原因は1つに絞り込めておらず、複数の要因が絡んでいる可能性があります。
Claude Codeがcdによるディレクトリ変更をイベントとして扱っていること自体は、CwdChangedフックの存在からも裏付けられます。Claudeがcdを実行するたびにこのフックが発火する設計であり、ディレクトリの移動が内部的に離散的なイベントとして扱われていることがわかります。
もう一つの手がかりはフックの入力に含まれるcwdフィールドです。公式ドキュメントは、このフィールドについて「Claudeに追従し、cd実行後は新しいディレクトリになる」と説明しています。つまり作業ディレクトリはコマンドをまたいで引き継がれる設計であり、issueで報告されている食い違いは、Claudeの認識と実際の位置がずれたときに表面化するものと見られます。
CLAUDE_BASH_MAINTAIN_PROJECT_WORKING_DIRで元のディレクトリに戻す
環境変数のリファレンスには、この現象に直接対応する設定が載っています。CLAUDE_BASH_MAINTAIN_PROJECT_WORKING_DIRを有効にすると、メインセッションでBashまたはPowerShellのコマンドを実行するたびに、元の作業ディレクトリへ戻ります。
export CLAUDE_BASH_MAINTAIN_PROJECT_WORKING_DIR=1
claudeこのexportはターミナルのセッション内でのみ有効で、シェルを閉じれば設定は消えます。毎回のセッションで有効にしたい場合は、設定ファイルのenvブロックに書いておく方法もあります。書き込み先は用途によって異なり、~/.claude/settings.jsonなら自分の全プロジェクトに、プロジェクト直下の.claude/settings.jsonならバージョン管理に含めてチーム全員に、.claude/settings.local.jsonならそのプロジェクトの自分だけに適用されます。.claude/settings.local.jsonはClaude Codeが設定を保存すると自動でgitignore対象になりますが、手作業で作成した場合は自分でgitignoreに加える必要があります。
{
"env": {
"CLAUDE_BASH_MAINTAIN_PROJECT_WORKING_DIR": "1"
}
}値は1またはtrueで有効、0またはfalseで無効です。公式ドキュメントの説明文は対象を「メインセッション」に限定しており、サブエージェント内のBash実行にも同じ挙動が適用されるかどうかは明記されていません。CwdChangedフックの発火条件も「メインの会話でのシェルコマンド」に限られます。サブエージェントを多用するワークフローでは、この前提の違いを踏まえて実際に確認しておくと安全です。
この変数を有効にすると、Claudeがcdで移動した直後でも、次のBashコマンドは常に元のプロジェクトルートから始まります。issueで報告されていたような「別ディレクトリのつもりでrmやgit reset --hardを実行する」事故のリスクを、構造的に減らせる設定です。稼働中のセッションでも、設定ファイルを保存すればその時点から新しい値が反映されます。
CwdChangedフックとステータスラインでズレを可視化する
環境変数で戻す以外に、ズレを検知・可視化する手段も公式に用意されています。CwdChangedフックは、cdなどで作業ディレクトリが変わるたびに発火するイベントです。ディレクトリ移動そのものを止める権限は無く、あくまで移動が起きた後に反応する設計ですが、old_cwdとnew_cwdをログに記録しておけば、いつどこへ移動したかを事後に追跡できます。発火条件もCLAUDE_BASH_MAINTAIN_PROJECT_WORKING_DIRと同じく「メインの会話でのシェルコマンド」に限定されており、サブエージェント内のcdまで捕捉するかは公式に明記されていません。Claude Codeのフック機構全体はHooks完全ガイドで扱っており、CwdChanged以外のイベントもそちらで確認できます。
もう一つの手段がステータスラインです。workspace.current_dirを表示に含めておけば、画面の下部でClaudeが今どこにいると認識しているかを常に確認できます。
{
"statusLine": {
"type": "command",
"command": "jq -r '\"[\\(.model.display_name)] \\(.workspace.current_dir)\"'"
}
}CLAUDE_BASH_MAINTAIN_PROJECT_WORKING_DIRで自動的に戻すのが根本対策だとすれば、ステータスラインは「戻っていないことにすぐ気づく」ための補助策にあたります。
使い分け早見表
| 手段 | できること | できないこと |
|---|---|---|
CLAUDE_BASH_MAINTAIN_PROJECT_WORKING_DIR | できること各Bash/PowerShellコマンド後に元のディレクトリへ自動で戻す | できないことサブエージェントへの適用は未確認 |
CwdChangedフック | できること移動の発生をログ記録・外部通知する | できないこと移動自体をブロックできない |
ステータスラインのworkspace.current_dir | できること現在の認識場所を画面に常時表示する | できないことズレの発生そのものは防げない |
CLAUDE_CODE_HIDE_CWD | できること起動ロゴのパス表示を隠す | できないことこの現象の解消とは無関係 |
CLAUDE_CODE_HIDE_CWDは名前が似ているため混同しやすい変数です。役割は起動ロゴに表示されるパスを隠してOSのユーザー名を画面共有で見せないことだけで、Claudeが実際にどこで動くかには一切影響しません。
事故そのものを減らしたいならCLAUDE_BASH_MAINTAIN_PROJECT_WORKING_DIRを有効にし、それでも不安が残るセッションではCwdChangedフックのログとステータスラインの表示を併用する、という組み合わせが実務的な落としどころです。
それでも起きたときの安全策
git worktreeを使っているセッションでは、ステータスラインのworktree.original_cwdでworktreeに入る前のディレクトリを確認できます。このフィールドはClaude Codeがworktreeセッションに入っているときだけ現れ、通常のメインの作業ツリーでは表示されません。複数のworktreeを行き来する運用では、この値も合わせて見ておくと現在地の把握に役立ちます。workspace.current_dirだけでは元のツリーへ戻ったのか単に別のworktree内を移動しただけなのか区別できない場面で、worktree.original_cwdが判断材料になります。
破壊的なコマンドを実行する前に、Claudeへpwdの実行結果を確認させてから進めるのも有効な予防策です。rm -rfやgit reset --hardのような取り消せない操作は、相対パスでなく絶対パスを明示させることで、誤ったディレクトリでの実行事故を避けやすくなります。
よくあるつまずき
- ステータスラインに何も表示されない: ワークスペースの信頼(trust)ダイアログを承認していないと、ステータスラインは空欄のままです。
claude --debugのログにはworkspace trust not acceptedと記録されます。フォルダの信頼を承認すれば表示が始まります - チームの管理設定を上書きしようとして反映されない: 組織のmanaged settingsに書かれた変数は、ユーザー設定やプロジェクト設定の同名変数より優先されます。個人設定で無効化したい場合は管理者側の見直しが必要です
まとめ
Claude Codeが作業ディレクトリを見失う現象は、GitHub issue #1669として2025年6月から報告が続く既知の課題です。公式ドキュメントは根本原因こそ説明していませんが、workspace.project_dirとworkspace.current_dirが食い違いうることは明記しています。
対処の軸は2つです。CLAUDE_BASH_MAINTAIN_PROJECT_WORKING_DIRで各コマンド後に元の場所へ戻す設定と、CwdChangedフックやステータスラインでズレの発生に気づける状態を作っておくことです。特に破壊的な操作を任せるセッションでは、この2つを組み合わせておく価値があります。
どちらもissueへの直接の回答としてAnthropicが用意したものではなく、環境変数とフックの一般的なリファレンスに載っている既存の仕組みです。挙動そのものが解消したとは断定せず、手元の設定でリスクを抑えておくという選択肢があります。