# Atlas error: tool call denied by a permission rule

> Read the ruleset JSON in the denial message, then change the matching rule in your config permission block from deny to ask or allow.

Atlas denied the tool call because Permission.evaluate matched the tool against your merged ruleset and the last matching rule had the action deny, so the fix is to read the ruleset JSON that Atlas serialized into the error message, find the rule that matched, and change it from deny to ask or allow in the permission block of your config. Atlas never shows an approval prompt for a denied call, because every Atlas tool call is permission-gated against allow, ask, and deny rules before it runs. If you hit the denial while the plan agent is active, do not loosen the rules; switch to the build agent instead.

## Symptom

The tool call never prompts for approval. The model is told: The user has specified a rule which prevents you from using this specific tool call. Here are some of the relevant rules <json>.

## Cause

Permission.evaluate matches the tool and its pattern against the merged ruleset with Wildcard.match and takes the last matching rule. When that rule's action is deny, Atlas raises PermissionDeniedError and serializes the relevant ruleset into the message.

## Fix

1. Read the ruleset JSON in the denial message. Atlas serializes the relevant rules into the message, so the JSON shows exactly which rule matched.
2. Open the `permission` block in your Atlas config and locate the rule you just identified in that JSON.
3. Change that rule's action from deny to ask, so Atlas prompts you, or to allow, so Atlas runs the tool without prompting.
4. Remember that the last matching rule wins. A broad allow placed before a narrow deny will not override the deny, so move or delete the deny rather than stacking an allow in front of it.
5. If the denial happens while you are in plan mode, edit is denied by design. Switch to the build agent instead of loosening the ruleset.
6. Re-run the exact tool call that failed and confirm Atlas either executes it or prompts you, rather than raising PermissionDeniedError again.

## Why does Atlas say a rule prevents this specific tool call

Atlas raises PermissionDeniedError when Permission.evaluate finds that the last rule matching your tool call carries the action deny. Every Atlas tool call is gated against 3 kinds of rule, allow, ask, and deny, so a deny short-circuits the call and 0 approval prompts are ever shown to you.

The message you see is not a bug report, it is a policy decision. Atlas evaluates the tool name and its pattern against the merged ruleset, and when the winning rule says deny, Atlas stops the call and tells the model: The user has specified a rule which prevents you from using this specific tool call. Here are some of the relevant rules <json>. The model then reports the denial back to you. Because the check happens before execution, nothing was run, nothing was written, and no file was touched. The ruleset JSON attached to the message is the useful part: Atlas serializes the relevant rules so you do not have to guess which of your config entries fired. Start there rather than editing config blindly.

## How Atlas resolves permission rules and why the last match wins

Atlas resolves permissions by taking the last matching rule, not the most specific one. Permission.evaluate runs Wildcard.match across the merged ruleset in order, so 1 broad allow placed before a narrow deny will never override that deny. Rule order inside your config decides the outcome of every tool call.

Last-match-wins is the single most common source of confusion here. Developers frequently add an allow rule at the top of the permission block, re-run the tool, and get PermissionDeniedError again, because a later deny still matches and still wins. The merged ruleset is what Atlas evaluates, so rules from every layer of your configuration participate in that ordering. If you want a narrow allow to take effect, it has to come after the deny that is currently matching, or the deny has to go. Reading the serialized ruleset in the error message tells you exactly which entry is winning, which is faster than reasoning about the merge by hand. Match patterns are wildcard patterns, so a rule you intended to be narrow may be matching far more broadly than you expected.

## How to fix a deny rule in your Atlas permission config

To fix a denied Atlas tool call in 2026, open the ruleset JSON that Atlas serialized into the error message, locate the rule that matched, then edit the `permission` block in your config to change that rule's action from deny to ask or allow. Two edits, no restarts, no flags.

Choosing between ask and allow is a real decision, not a formality. Setting the rule to ask means Atlas pauses and prompts you every time the tool call comes up, which keeps a human in the loop on anything sensitive. Setting the rule to allow means Atlas runs the tool without prompting, which is the right call for genuinely routine operations you have already decided to trust. Be honest about the tradeoff: a deny rule usually exists because someone, possibly you, decided the tool should never run in this context. Before you relax it, confirm the rule is actually wrong rather than merely inconvenient. If the rule is correct and the tool call is the problem, change what the agent is asking to do instead of changing the policy that stopped it.

## Why plan mode denies edits and what to do instead of editing rules

Plan mode in Atlas denies every edit by design, so loosening permission rules is the wrong fix when the denial arrives during planning. Atlas drafts a plan in a read-only plan agent and asks before switching to a build agent, and 1 switch to that build agent is the intended route.

If the PermissionDeniedError shows up while the plan agent is active, the ruleset is doing its job. The plan agent exists to produce a plan without touching your working tree, and the edit denies are the mechanism that makes the read-only promise real. Adding a global edit allow to get past the message defeats the mode entirely and gives you a plan agent that silently writes files. The supported path is to finish the plan and switch to the build agent, which merges the default permissions rather than the plan agent's denies. Once you are on the build agent, the same edit that was denied a moment ago will proceed through the normal approval flow, where Atlas computes a unified diff for every file edit and surfaces it for approval before writing.

## How to verify the permission fix worked in Atlas

Verify an Atlas permission fix by re-running the exact tool call that failed. A correct fix produces 1 of 2 outcomes: the call executes when the last matching rule is allow, or Atlas prompts you when that rule is ask. Seeing PermissionDeniedError again means a deny still matches last.

A repeat denial after an edit almost always means one of two things. Either the rule you changed was not the rule that was actually matching, in which case go back to the serialized ruleset JSON in the new error message and read it again, or you added an allow before the deny and last-match-wins ignored it. Confirm by comparing the JSON in the fresh error against the config you just edited. If the two disagree, your edit landed in a layer that is being overridden by a later one. When the fix is correct, the difference is immediate and unambiguous: an ask rule produces a visible approval prompt, and an allow rule produces tool output. There is no third, ambiguous state to interpret.

## FAQ

### what does the user has specified a rule which prevents you from using this specific tool call mean

That message means Atlas evaluated your tool call against the merged permission ruleset and the last matching rule had the action deny. Atlas raised PermissionDeniedError before running the tool and serialized the relevant rules into the message so you can see which one matched.

### how do I allow a tool that Atlas keeps denying

Read the ruleset JSON in the denial message to find the rule that matched, then edit the `permission` block in your Atlas config and change that rule's action from deny to allow. If you want a prompt instead of silent execution, set it to ask.

### why does my allow rule not override the deny in Atlas

Atlas takes the last matching rule, not the most specific one. Permission.evaluate runs Wildcard.match over the merged ruleset in order, so a broad allow placed before a narrow deny does not override it. Move the allow after the deny, or remove the deny.

### why is Atlas denying edits in plan mode

Plan mode denies edit deliberately. Atlas drafts a plan in a read-only plan agent and asks before switching to a build agent, and the deny rules are what keep the plan agent read-only. Switch to the build agent rather than loosening the ruleset.

### does Atlas prompt me before a denied tool call runs

No. A deny rule means no prompt at all. Every Atlas tool call is permission-gated against allow, ask, and deny rules before it runs, and only ask produces a prompt. A deny raises PermissionDeniedError and the tool never executes.

### where is the permission block in the Atlas config

Permission rules live in the `permission` block of your Atlas config. Atlas merges the rules from your configuration layers into a single ruleset, and Permission.evaluate matches tool calls against that merged set with Wildcard.match.

### how do I know which Atlas permission rule denied my tool call

Atlas serializes the relevant ruleset into the PermissionDeniedError message. Read that JSON and it shows exactly which rule matched. Do not guess from your config, because the merged ruleset and last-match-wins ordering can produce a different winner than you expect.

---

Canonical HTML: https://runatlas.sh/resources/troubleshooting/permission-denied-by-rule
Source of truth: aeo_pages row `/resources/troubleshooting/permission-denied-by-rule` (segment: Troubleshooting) (this file is generated from it, never hand-edited).
Licence: Atlas is proprietary with a free core. It is not open source and there is no public source repository.
