12.13 Denial Tracking and Degradation
When the model's tool calls are repeatedly denied, Claude Code tracks the denial count and triggers a degradation strategy:
// src/utils/permissions/denialTracking.ts
type DenialTrackingState = {
consecutiveDenials: number // Consecutive denial count
totalDenials: number // Total session denial count
}
const DENIAL_LIMITS = {
maxConsecutive: 3, // 3 consecutive denials
maxTotal: 20, // 20 total denials
}When consecutive denials reach 3 or total denials reach 20, shouldFallbackToPrompting returns true, and the system triggers degradation:
- In auto mode: Aborts automatic decision-making, falls back to interactive confirmation
- In headless mode: Aborts Agent execution, throws an error
The recordSuccess function resets the consecutive denial counter when a tool call succeeds (but does not reset the total count). This means that if the model successfully executes other operations after being denied, the "consecutive denials" counter resets to zero—the system assumes the model has adjusted its strategy.
This mechanism addresses a common problem: the model may not understand why a certain operation was denied, then repeatedly attempts the same denied operation. Once the denial tracker detects this pattern, it injects additional information into the system prompt, guiding the model to adopt alternatives rather than continuing to hit the wall.
Source:
src/utils/permissions/denialTracking.ts