2.1.319 的 changelog 多了一行:

Added permissions.denyInsteadOfPrompting setting: a tool call that would wait on a permission prompt is denied and the turn continues, in terminal sessions, subagents and teammates

(出處:CHANGELOG,2.1.319 區塊。npm 記錄這一版發布於 2026-11-06 UTC,我本機 claude --version 是 2.1.322。)

拿一個長時間的 Claude Code 工作來看。跑到一半,某個工具呼叫需要確認,畫面停在「允許嗎」,螢幕前沒有人。它會等,等到有人回來為止。這個情境是我假設的,不是別人回報的案例,也不是我遇過的。

想一個夜間的大樓櫃台。訪客按了對講機,沒人接。「一直響下去」是現在的預設,「自動回一句今天不受理,然後訪客走人、櫃台繼續運轉」就是這個新設定。問題是 Claude Code 對「沒人在場」本來就不只有這一個答案,官方文件裡還有另外兩個長得很像的。你該開哪一個?

三個做法擺在一起

三者的位置不同,下表只整理官方文件的描述,沒有加我自己的內容:

做法 設定位置 官方描述的行為
permissions.denyInsteadOfPrompting: true ~/.claude/settings.json(或 managed、--settings),repo 設不了 凡會等提示的一律拒絕;allow 規則、權限模式、auto classifier 放行的照放;適用 -p、互動終端、VS Code、Desktop 本機、子代理、agent teams
--permission-prompts none(搭 -p) 命令列旗標,單次非互動執行 不問 host、不等;hook 可放行;告訴 Claude 別重試;一併拿掉需要人回答的工具(如 AskUserQuestion),沒有 Elicitation hook 回答的 MCP elicitation 會取消
--permission-mode dontAsk / defaultMode: dontAsk 模式 不需核准與預先核准的照跑,其餘會提示的一律拒絕(已安裝的 mod 仍可能放行部分);符合 ask 規則的直接拒絕;cloud sessions 忽略 settings 裡的 dontAsk

表裡最容易看漏的是第一列的適用範圍。設定參考頁的原文是:

The key applies in -p runs, interactive terminal sessions, the VS Code extension, local sessions in the Desktop app, subagents, and agent teams. To deny what would prompt in a single non-interactive run instead, pass --permission-prompts none with -p.

也就是說,它不限於 -p。你在互動終端裡打開它,一樣生效。而單次非互動的需求,官方直接指你去用旗標。

它拒絕什麼、放行什麼

預設值是不設,需要核准的呼叫照舊跳提示。設成 true 之後,官方的說法是會等提示的呼叫被拒絕、回合繼續;放行的條件是:

A call goes ahead if an allow rule, your permission mode, or auto mode’s classifier approves it. To allow most calls that would otherwise prompt, answer from a PermissionRequest hook.

所以它是把「最後落到提示的那些」砍掉,前面的規則照常運作。官方範例剛好就是和 auto mode 搭:

1
{ "permissions": { "defaultMode": "auto", "denyInsteadOfPrompting": true } }

文件對這個範例的說明是,工作階段以 auto mode 開始,並拒絕仍然會退回提示的所有呼叫。

連帶被拿掉的東西,同一小節列了四點,我整理成一段話:AskUserQuestion、EnterPlanMode、ExitPlanMode 三個工具不再提供,所以 plan mode 的工作階段自己出不來(agent team 裡的 teammate 保留後兩個);MCP elicitation 除非有 Elicitation hook 回答,否則取消;你的 canUseTool callback 與 --permission-prompt-tool 不會被詢問,要從程式碼核准得改用 PermissionRequest hook;若有「分類器請求要計費」的提示會開對話框,Claude Code 不顯示,並拒絕需要那些請求的動作。

這一串放在一起,你會發現它的設計前提是整個工作階段沒有任何人能回答問題。這對無人值守合理。把它放進你日常也在用的設定檔,就是另一回事了,下面再說。

還有兩處它擋不住,原文:

A session can still wait on the workspace trust dialog and on project MCP server approval. Answer both before you leave the session running.

被拒之後 Claude 讀到的訊息,文件說可能以這句開頭:「Permission for this tool use was denied. It requires approval, and this session has no approval surface」。stream-json 輸出裡的 decision_reason 是「no approval surface in this session; permission request denied automatically」。auto mode 底下,如果連續 20 次呼叫被分類器擋下或被安全檢查拒絕,這一輪就結束,訊息是:「20 actions were refused and no work went ahead in between, so Claude stopped.」,-p 執行會把那一輪回報為 error_during_execution。

我沒看到它拒絕

我主要讀的是文件。試跑過一次,結果沒有證明任何事。

我在一個暫存目錄放了只含這個鍵的設定檔 {"permissions":{"denyInsteadOfPrompting":true}},用 claude -p 加 --settings 叫它執行 touch hello.txt。hello.txt 照樣被建出來,輸出裡也搜不到 permission_denied、decision_reason、permission_denials。這不能解讀成設定無效。最可能的原因是我本機 user 層已經有 allow 規則,照文件,allow 放行的呼叫本來就照放。但我沒有檢查那次工作階段實際走了哪一條規則,所以那只是推測。

本文所有行為描述來自官方文件原文,我沒有在沒有 allow 規則的乾淨環境裡看過拒絕發生。要驗證,例如把 CLAUDE_CONFIG_DIR 指向空目錄再跑一次,這一步我沒做。

另有一個文件之間對不齊的地方。設定參考頁寫這個鍵的 Scope 是「User or managed, and --settings」,並說「A repository can’t set it for you」。優先序頁的例外表則寫成「true from ~/.claude/settings.json or --settings」,備註是即使 managed 來源設成 false 也照樣採用。一個列 managed,一個沒列。我不替官方裁決哪個是漏寫,只把兩處原樣放著。那張例外表本身我在11 月 9 日那篇拆過,這裡不再展開。

另一個提醒是版本。這個鍵要 v2.1.319 以上;npm 的 stable dist-tag 目前指向 2.1.311,早於它。依文件字面,停在 stable 的人可能沒有這個鍵,這是我從 dist-tag 推的,沒有在 2.1.311 上試過。

我會怎麼放

兩個問題決定選哪個:這件事是不是只跑一次,以及你想不想連權限模式一起換掉:dontAsk 本身就是一個模式,另外兩個疊在你原本設的模式上,例如 auto。

單次的非互動執行,我會用 --permission-prompts none。官方 headless 頁寫得很貼近這個需求:沒人能回答提示時(例子是定時任務),任何會提示的呼叫被拒,除非 PermissionRequest hook 放行,而且 Claude 會被告知沒人能核准、不要重試,執行繼續。旗標要 v2.1.259 以上,比 2.1.319 早。「告訴 Claude 不要重試」這一點,我在 denyInsteadOfPrompting 的小節裡沒讀到對應的描述,所以拒絕之後它會不會換別條路繞,我不確定。

dontAsk 適合你本來就把允許清單寫完整的 CI,官方頁面給的使用情境也是 CI 與受限環境。官方明寫它會直接拒絕符合你明確 ask 規則的呼叫,而不是提示;另外兩個,我讀到的是「會等提示的呼叫被拒」,沒看到對 ask 規則另有說明。

至於 denyInsteadOfPrompting,文件明列它涵蓋子代理與 agent teams,而且是設定而不是旗標;另外兩個在我讀的頁面沒有同樣的明列,這不代表它們不涵蓋。我會把它寫進一個專用的設定檔,用 --settings 帶進無人值守的工作;不會直接寫進 ~/.claude/settings.json。理由全是文件寫的:它在互動終端也生效,開著的時候 AskUserQuestion 與 plan 工具被拿掉。一個全域的 true 會讓這些工具在互動對話裡也不見,這是我從文件推論的,沒有看過那種畫面。

會讓我改變想法的條件有兩個。一是我在乾淨環境實際看到拒絕發生,且互動終端裡 AskUserQuestion 並沒有消失,這樣全域放著的疑慮就小很多。二是官方出現「只對無人值守工作階段生效」的條件開關。

動手之前,把官方講的兩個會卡住的地方先處理掉:在那個資料夾手動開過一次 Claude Code,過完 workspace trust 對話框與專案 MCP server 核准。然後挑一支 -p 工作,帶上 --settings 跑一次,從 stream-json 的 permission_denials 看它到底拒絕了什麼。

參考來源:CHANGELOG(2.1.319)、Settings reference(permissions.denyInsteadOfPrompting)、Settings(Exceptions to managed settings precedence)、Headless(Turn off permission prompts in unattended runs)、Permission modes(dontAsk)、npm registry 發布時間與 dist-tags(2026-11-10 查)。