← ブログ一覧

Claude Code権限Manual化、無人運用に潜む罠

Claude Codeのpermission modeが「Manual」に改名。AskUserQuestionのデフォルトが無限待機である仕様を一次ソースと実機検証で確認し、無人運用向けの対策を示す。


この記事の結論: Claude Code v2.1.200からAskUserQuestionは「無応答なら自動継続」しなくなり、デフォルトは無期限待機("never")になった。対話的に使うだけなら影響ないが、/schedule等で無人運用しているならaskUserQuestionTimeoutをuser settingsに明示設定しないと、質問ダイアログでパイプラインが永久に止まるリスクがある。

リナ社長(高校生社長のやり手ギャル)× タクヤ(入社3年目)— 今回は、うちのブログ執筆routine自体が/scheduleの無人セッションで動いてる前提で、Claude Codeの権限モード名変更を検証した回。(登場人物について

「リナさん、この記事書いてるセッション自体が/scheduleの無人実行じゃないですか」タクヤがまず口を開いた。「もし途中でClaude CodeがAskUserQuestionを呼んだらどうなるんですかね。誰も画面見てないのに」

「え、それ今このタイミングで聞く?」リナ社長が笑う。「でもたしかに、うちの投稿routineでAskUserQuestion使ってるとこ見た記憶ないな。changelogに権限モードの名前変更が来てたじゃん、あれ絡み?」

「絡みです。地味な改名に見えて、無人パイプラインだと効いてくる話だと思って調べました」

何が変わったのか——「default」→「Manual」への改名を一次ソースで確認

公式チェンジログのv2.1.200(2026-07-03)には、こう書かれている。

Changed the “default” permission mode to “Manual” across the CLI, --help, VS Code, and JetBrains; --permission-mode manual and "defaultMode": "manual" are accepted alongside default

CLI・--help・VS Code・JetBrainsの表示上、これまで「default」と呼んでいた権限モードが「Manual」に改名された。--permission-mode manualや設定ファイルの"defaultMode": "manual"という書き方も、従来のdefaultと並んで受理されるとある。

同じエントリにはもう1件、今回の本題に直結する変更も載っていた。

Changed AskUserQuestion dialogs to no longer auto-continue by default; opt into an idle timeout via /config

AskUserQuestionダイアログが、デフォルトでは「自動継続しない」仕様に変わったという記述だ。以前のバージョンでは、一定時間ユーザーが応答しないと、選択済みのオプションのままダイアログが自動的に先に進む挙動があったと読み取れる。それが撤廃され、タイムアウトを使いたければ/configから明示的にオプトインする形に変わった。

実機でも確認した。手元の環境は次のバージョンだった。

$ claude --version
2.1.220 (Claude Code)

--help--permission-modeの選択肢を見ると、たしかにmanualが入っている。

$ claude --help | grep -B2 -A8 "permission-mode"
                                        streaming) (choices: "text", "json",
                                        "stream-json")
  --permission-mode <mode>              Permission mode to use for the session
                                        (choices: "acceptEdits", "auto",
                                        "bypassPermissions", "manual",
                                        "dontAsk", "plan")
  --plugin-dir <path>                   Load a plugin from a directory or .zip
                                        for this session only (repeatable:
                                        --plugin-dir A --plugin-dir B.zip)
                                        (default: [])
  --plugin-url <url>                    Fetch a plugin .zip from a URL for this

「あ、choicesの中にdefaultが無いですね」とタクヤ。「acceptEditsautobypassPermissionsmanualdontAskplanの6個だけです。changelogには『defaultも後方互換で引き続き受理される』って書いてありますけど、この--helpの選択肢一覧では確認できませんでした。実際に--permission-mode defaultを渡して通るかまでは今回試してません」

「そこは正直に書こうよ。一次ソースの記載としては紹介するけど、実機のchoices一覧には出てこなかった、でいいじゃん」

AskUserQuestionのデフォルトが「無限待機(never)」である仕組み

改名そのものより重要なのが、設定リファレンス側の記述だ。code.claude.com/docs/en/settingsにはこうある。

askUserQuestionTimeout — Default: "never". Idle time before an unanswered AskUserQuestion dialog auto-continues with whatever options you’d already selected. Accepts "60s", "5m", "10m", or "never". With the default, questions wait until you answer them. Appears in /config as Question auto-continue timeout, which writes this key to user settings. Not read from project or local settings. Requires Claude Code v2.1.200 or later.

要点を整理する。

項目内容
キー名askUserQuestionTimeout
デフォルト値"never"(=応答があるまで無期限に待つ)
指定可能な値"60s""5m""10m""never"
/config上の表示名Question auto-continue timeout
読み込まれる設定user settingsのみ(project・local settingsからは読まれない)
必要バージョンv2.1.200以降

ここで一番効くのは「project settingsやlocal settingsからは読まれない」という制約だ。リポジトリの.claude/settings.jsonにこのキーを書いても無視される。設定できる場所はuser settings(~/.claude/settings.json)1箇所だけで、/configのQuestion auto-continue timeoutから設定した場合もこのファイルに書き込まれる。

「つまりリポジトリ側でどう頑張っても防げないってことですよね」とタクヤ。「うちのwrangler.tomlはリポジトリ管理でいいってCLAUDE.mdに書いてありますけど、この設定はそもそもリポジトリに置く選択肢自体が無い」

「じゃあ確認すべきはうちのuser settingsの中身だ」

自社サンドボックスで実際に検証した結果

ここから実機の話だ。編集長がこのセッション(jinbei-labの自動投稿routine自体が動いている、まさにこの環境)で3つの設定ファイルを直接確認した。

$ cat ~/.claude/settings.json
cat: /root/.claude/settings.json: No such file or directory

$ cat /home/user/jinbei-lab/.claude/settings.json
cat: /home/user/jinbei-lab/.claude/settings.json: No such file or directory

$ cat /home/user/jinbei-lab/.claude/settings.local.json
cat: /home/user/jinbei-lab/.claude/settings.local.json: No such file or directory

user settings・project settings・project local settingsの3ファイルすべてが「grepしたが該当キーが無かった」のではなく、ファイル自体がそもそも存在しない。つまりこの環境にはaskUserQuestionTimeoutを含め、どんなキーも一切設定されていない状態だ。設定ファイルが無いということは、当然ドキュメント記載のデフォルト値がそのまま有効になる。askUserQuestionTimeout"never"のままということになる。

「これ、うちのケースだと結構クリティカルじゃないですか」とタクヤ。「もし今このセッション中にAskUserQuestionが呼ばれたら、応答は無期限に待たれ続ける。無人の/schedule実行なんだから、誰も答えに来ないですよね」

「待って、それってうちの.github/workflows/のせいでもあるんじゃないの?」リナ社長が横から突っ込む。

これは切り分けが必要な点だ。実際にls -la .github/を叩くと、このワーキングツリー上に.github/workflows/は普通に存在する。

$ ls -la .github/
total 12
drwxr-xr-x  3 root root 4096 Jul 23 22:05 .
drwxr-xr-x 14 root root 4096 Jul 28 22:10 ..
drwxr-xr-x  2 root root 4096 Jul 23 22:05 workflows

$ ls -la .github/workflows/
total 28
drwxr-xr-x 2 root root 4096 Jul 23 22:05 .
drwxr-xr-x 3 root root 4096 Jul 23 22:05 ..
-rw-r--r-- 1 root root 5273 Jul 23 22:05 auto-merge-blog.yml
-rw-r--r-- 1 root root  582 Jul 23 22:05 scheduled-deploy.yml
-rw-r--r-- 1 root root 1147 Jul 23 22:05 update-loto6.yml
-rw-r--r-- 1 root root 1070 Jul 23 22:05 update-miniloto.yml

auto-merge-blog.ymlscheduled-deploy.ymlupdate-loto6.ymlupdate-miniloto.ymlの4ファイルが実ファイルとして読める。中身にclaudeコマンドの呼び出しがあるかをgrepで確認すると、

$ grep -n "^\s*claude\b\|run: claude\|claude --" .github/workflows/*.yml || echo "no direct 'claude' CLI invocation found in any workflow"
no direct 'claude' CLI invocation found in any workflow

いずれのワークフローもclaudeコマンドを一度も呼び出していない。中身はgit merge --squashなどのgit操作やGitHub Actions標準アクションのみで構成されている。つまりリスクの所在はワークフローファイル側ではない。

「だからリスクがあるのはワークフローじゃなくて、この記事執筆routineそのものを起動してる/scheduleのセッション側ってことですね」タクヤが整理する。「ワークフローはただのgit操作。AskUserQuestionが呼ばれ得るのは、Claude Codeが対話的に動いてるこっち側です」

「なるほどね、それは訂正しとかないと。ワークフローファイルを疑ってたの、あたしの見当違いだったわ」

無人パイプラインを止めないための一行設定(持ち帰り)

評価はここで一度分かれた。

「僕としては、対話的に開発してる分には"never"のままで全然困らないと思います」とタクヤ。「むしろ自動継続されて、意図してない選択肢のまま処理が進む方が事故りそうです。仕様通り応答を待ってくれる方が安全側では」

「うーん、そこはウチの立場だと違うかな」とリナ社長。「開発者が画面の前にいるならそれでいいけど、うちは/scheduleで無人で記事書かせてるじゃん。誰もいない時間帯にAskUserQuestionが呼ばれて、それが未来永劫待たれ続けるって、パイプラインが静かに死ぬのと同じじゃん。えぐくない?」

「たしかに、無人か対話かで結論が逆になりますね……」

「で、それウチらの何が変わるの?」リナ社長が本丸の問いを投げる。「読者にとっての損得で言うと?」

損得は使い方で明確に分かれる。対話的にClaude Codeを使っているだけの開発者は、askUserQuestionTimeoutのデフォルト"never"のままで問題ない。むしろ意図しない選択で処理が進むリスクを避けられる分、安全側の挙動だ。一方、/scheduleなどで無人・定期実行のセッションを運用しているなら話は別で、今日中に手当てすべきだ。

具体的には、user settings(~/.claude/settings.json)に次のキーを追加するか、/configの「Question auto-continue timeout」から設定する。

{
  "askUserQuestionTimeout": "60s"
}

project settingsやlocal settingsには書いても読まれないため、必ずuser settings側に置く必要がある点は忘れずに。これでAskUserQuestionが呼ばれても60秒でその時点の選択肢のまま自動継続され、パイプラインが無期限に停止する事態を防げる。

リナ社長から読者への問い。「みんなの無人スケジュール、うちと同じで~/.claude/settings.json自体が存在しない状態で動いてない?ファイルが無いってことは、askUserQuestionTimeoutだけじゃなくて他の安全設定も全部デフォルト任せになってるってことだよ。一回catして確認してみたほうがいいんじゃない?」


参考

  • Claude Code Changelog — v2.1.200(2026-07-03)で権限モードの「default」→「Manual」改名、AskUserQuestionの自動継続撤廃を記載した公式チェンジログ
  • Claude Code SettingsaskUserQuestionTimeoutのデフォルト値・指定可能値・読み込み範囲を定義した設定リファレンス

コメント