anthropics / anthropics/claude-code
[BUG] PermissionRequest hook: permission_suggestions does not match the rows the permission dialog actually shows
- Langage dominant
- Python
- Étoiles
- 145k
- Forks
- 23.1k
- Métriques de merge des PR
- Métriques de PR en attente
Description
### Preflight Checklist
- [x] I have searched existing issues. Closest: #28464 (permission_suggestions inconsistencies with the UI, closed not-planned; its closing comment asks for a new issue referencing it) and #43384 (empty permission_suggestions for .claude/ writes in acceptEdits mode, closed). This report is a different, still-reproducible divergence: the dialog's auto-mode row is absent from `permission_suggestions`, while a `setMode` suggestion the dialog does not display is present.
- [x] This is a single bug report
- [x] I am using the latest version of Claude Code (2.1.252)
### What's Wrong?
The hooks documentation describes `permission_suggestions` as the pre-computed permission updates offered to the user in the normal permission dialog ("When no hook decides, the normal permission prompt is shown with these suggestions as buttons"). In practice the two can diverge in both directions for the same tool call:
1. The dialog shows a row that is not present in `permission_suggestions`: "Yes, and switch to auto mode".
2. `permission_suggestions` contains an entry the dialog does not show: `{"type": "setMode", "mode": "acceptEdits", "destination": "session"}`. When auto mode is available, the dialog appears to display its auto-mode row instead of a row for this suggestion.
So a PermissionRequest hook that wants to present the dialog's choices (or echo one back via `updatedPermissions`, documented as "equivalent to selecting it in the dialog") cannot reconstruct what the dialog actually offers: it receives an option the user never sees, and never receives an option the user does see.
Observed hook input for a Bash `rm` on a path outside the project (abridged):
```json
{
"hook_event_name": "PermissionRequest",
"tool_name": "Bash",
"tool_input": { "command": "rm /Users//some-file.txt" },
"permission_suggestions": [
{ "type": "addDirectories", "directories": ["/Users/"], "destination": "session" },
{ "type": "setMode", "mode": "acceptEdits", "destination": "session" }
]
}
```
Dialog shown for the same call:
```
1. Yes
2. Yes, and always allow access to /Users/ from this project
3. Yes, and switch to auto mode · auto mode handles these prompts for you
4. No
```
No `setMode: "auto"` entry is present in the hook input, and no acceptEdits row is shown in the dialog. (Minor related note: the `addDirectories` entry carries `"destination": "session"` while the dialog wording says "from this project".)
### What Should Happen?
`permission_suggestions` matches the dialog: every row backed by a permission update appears in the array, and entries that the dialog will not display are not sent. If the auto-mode row is intentionally dialog-internal, documenting that (and not sending the suppressed `setMode` suggestion) would also resolve the ambiguity.
### Steps to Reproduce
1. Register a logging PermissionRequest hook that returns no decision, e.g. in `settings.json`:
```json
{
"hooks": {
"PermissionRequest": [
{ "matcher": "Bash",
"hooks": [ { "type": "command", "command": "tee -a /tmp/permission-request.log >/dev/null" } ] }
]
}
}
```
2. In default permission mode, with auto mode available, ask Claude to run a Bash command that needs approval and touches a path outside the project (e.g. `rm /Users//some-file.txt`).
3. Compare the logged `permission_suggestions` with the dialog rows.
### Environment
- Claude Code 2.1.252 (native install), macOS 26
- Default permission mode, auto mode available
Guide de contribution
Aucun guide de contribution indexé pour ce dépôt
Piste de recherche
Start with the PermissionRequest hook in settings.json, reproduce the Bash approval using the logging command, and compare the recorded permission_suggestions with the displayed dialog rows. Trace the entry points that build both representations; done means the hook data and dialog agree, or the documented behavior clearly explains any intentionally internal row.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Évaluation
- Stack technique
- python
- Domaine
- cli, security
- Type d'issue
- Bug
- Difficulté
- 4/5
- Temps estimé
- 3-5 jours
- Activité
- Active
- Clarté
- Plutôt claire
- Accessibilité débutants
- 52/100