This page helps when a policy does not decide what you expect, when an approval is missing or cannot be signed, and when a call that was allowed or approved is refused before it runs.
Two tools answer most questions here:
- The action page. Open the call under Actions. Its Why card explains which rule (or the document default) decided and whether an observe window relaxed the decision; the page also shows the policy version and the reason code. Re-run as dry-run with today's policy checks the same call against the policy as it is now.
- The dry run. Test a call on an agent's page runs a call through the decision path without recording anything. It answers what the Gateway would decide now and which check would refuse. See Test and simulate.
The policy does not decide what you expect
A change has no effect
Cause. Saving in the policy editor creates a new draft version. A draft changes nothing: the Gateway always evaluates the policy's single active version, which it reads on every call.
Fix. Activate the version. Only owners and admins can activate, from the policy's Versions or Rollout tab. The policy page's Active version fact shows which version is in force.
Other causes of "my change has no effect":
| Cause | How to tell | Fix |
|---|---|---|
| The agent is bound to another policy | The agent page shows the agent's policy. | Switch the agent's policy (owner or admin), or edit the policy it uses. |
| An emergency stop is active | The policy page shows "An emergency stop is active" and the active version is labelled Emergency stop vN. | Roll back or activate a reviewed version once the incident is resolved. See Emergency stop. |
| An observe window is open for the agent | A banner on every organization page names the agent's open window. | See Observe and shadow are not enforcement. |
| You changed the shadow version | The policy page's Shadow fact shows "vN · not enforced". | Activate the version instead. |
Every call is denied with NO_POLICY
The agent has no policy, or its policy has no active version. The policy page then shows "No active version: every call of its agents is denied". Activate a version, or bind the agent to a policy that has one.
Rollback created a new version number
Rolling back does not reactivate the old version: it activates a byte-identical copy of it as a new version (version N+1, source restore). Old versions are immutable and stay superseded. This is expected; the copy's digest equals the original's.
Observe and shadow are not enforcement
People often expect a shadow version to protect them, or are surprised that observe lets calls through.
| What it does | What it never does | |
|---|---|---|
| Shadow | Names one non-active version of the policy whose decisions are computed afterwards, for comparison, in the shadow report and on action pages. | It never changes a decision. The Gateway does not read the shadow at all. |
| Observe | An owner or admin opens an observe window for one agent and chosen key environments. While it is in effect, calls the policy would deny or hold by its default are allowed and executed, and recorded as relaxed. With The default and approval rules selected for the window, require_approval rules without guard are relaxed too. | It never relaxes an explicit deny rule, a guarded approval rule, an emergency-stop version, or a check outside the policy (no delegation, no approvers, invalid amount and the like). |
An observe window relaxes calls only while all of these hold: the owner has observe switched on for the organization (a maximum window length above 0 and the live opt-in), the window is open and covers the calling key's environment, and the window is not longer than the organization's current maximum. A window ends when it expires, when an owner, admin or developer ends it (End now in the banner), when an owner switches observe off or lowers the maximum, on an emergency stop, when the agent is disabled, or when the agent is moved to another policy. Ending a window takes effect on the next call.
A relaxed call carries "enforcement": "observe" in its recorded decision, in the signed task and in the agent's result. See Observe and shadow.
The require-approval stage asks the wrong people
In the rollout's require-approval stage, the active version is a softened copy of the target version: each deny rule becomes a guarded require_approval rule with owners and admins as approvers, and the document default becomes require_approval. A call the target denies by its default is therefore held for an approval that any member with an approving role can decide: owner, admin or approver. Only calls denied by an explicit rule need an owner or admin.
A rule with an amount does not match
Amount rules compare the call's amount, which the Gateway reads from the tool's arguments with the tool's amount mapping (an amount pointer and a currency). Three situations surprise people:
| Situation | What happens |
|---|---|
| The call has no amount (the tool has no amount mapping, or the pointer finds nothing in the arguments) | deny and require_approval rules with an amount condition match (fail closed); allow rules with an amount condition do not match. The call falls through to other rules or the default. |
The value at the pointer is not an amount (a fractional or negative number, null, a malformed string…) | The call is denied INVALID_AMOUNT before the policy is evaluated. Amounts must be non-negative decimal strings or non-negative whole numbers. Observe never relaxes it. |
| The rule's currency differs from the call's | Treated like a missing amount: deny and require_approval rules match, allow rules do not. |
The winner among matching rules is the most restrictive one (deny, then require_approval, then allow); among equals the first in the document wins. With no matching rule the document default applies.
Fix. Check the tool's amount mapping on Tools & MCP servers, then run the call in a dry run: it shows the amount the Gateway extracted (or "no amount"), the decision and the limits that apply. See Rules, amounts and currencies.
The currency is wrong or ignored
| Tool configuration | Behaviour |
|---|---|
| Amount mapping without a currency pointer | Every amount is priced in the tool's currency. A currency argument in the call is not read at all. |
| Amount mapping with a currency pointer | The call must name exactly the tool's currency (the ISO 4217 code) at that pointer. A missing, different or ambiguous value is denied INVALID_AMOUNT. |
A delegation can carry a maximum amount. The K-Block engine refuses a call above it, a call in another currency, and a call without an amount (priced as 0 XXX): the call is denied with the reason code ENGINE_REFUSED, and the agent receives the code CONSTRAINT_VIOLATION with the engine's message in the detail. A dry run shows the delegation's per-call limit and the call's price under its Delegation constraints check. A delegation with a maximum amount therefore refuses every call of a tool that has no amount mapping. Give such a delegation only to actions whose tools price their calls in the delegation's currency.
No approval request appears
When the policy requires approval, the Gateway resolves the approvers at the moment of the decision. If it cannot, the call is denied instead of waiting.
| Reason code | Cause | Fix |
|---|---|---|
NO_APPROVERS | No member is eligible. An eligible approver has an approving role (owner, admin or approver), is admitted by the rule's approvers (its roles or its users list), is not disabled, and has an active personal K-Block identity. | Bind a personal identity on the Account page (account menu, Account settings), or widen the rule's approvers. |
TOO_MANY_APPROVERS | More than 32 members match. A K-Block task lists at most 32 approvers. | Narrow the rule: fewer roles, or a list of users. |
NO_PRINCIPAL | The organization has no principal. | An owner sets it under Settings. |
A rule without approvers is not valid on a require_approval rule; a require_approval default admits every approving role.
You cannot approve a request
Open the request under Approvals. Instead of Approve and sign and Reject and sign, the page tells you why you cannot decide:
| Message | Cause | Fix |
|---|---|---|
| "Your role cannot decide approvals. Owners, admins and approvers can." | Your role is developer or viewer. | Ask an owner, admin or approver. |
| "You cannot sign this decision from this browser" — "The deciding rule does not admit your role, or none of your bound identities is listed…" | The approver list is fixed when the request is created. A role or identity you gained later does not count for this request. | Someone listed decides it, or the agent calls again after the change to create a new request. |
| "You cannot sign this decision from this browser" — "None of your personal keys stored in this browser is listed…" | Your listed key is stored in another browser. | Use that browser, or import the key backup that holds the listed identity. |
| "This browser's key storage is not available, so your keys cannot be looked up here" | The browser refused access to the dashboard's storage, so the page cannot tell which of your keys are here. This is not the same as having no key. | Close other dashboard tabs and reload the page. If it stays, check that the browser lets this site store data: some private windows and privacy settings block it. |
| "Deciding is disabled until the signed evidence has been verified." | The browser verifies the signed task and proposal against the Gateway's identity before it lets you sign. | Wait for the check. If it fails, the page says why; do not decide until it passes. |
| "Approving is disabled: the tool's upstream binding changed after this call was decided…" | The tool changed since the decision; the Gateway would refuse to execute it. | Reject the request. The agent's next identical call gets a new decision. |
| "This request expired … and can no longer be decided." | See The approval expired. | — |
Any one listed approver decides; there is no quorum. Approving is possible only in a signed-in browser session, never with an API key.
The approved or allowed call does not run
An approval authorizes exactly one call: the same tool, arguments and target as decided. The agent runs it by repeating the identical call (or by waiting with kblock/wait-seconds). Before it executes, the Gateway checks again that nothing it was decided on has changed. When a check fails, nothing is executed and the approval is not consumed.
The tool or its server changed (stale binding)
An owner's or admin's authorization of a tool covers its whole upstream binding: the MCP server, its URL, server KID and credential, the upstream tool, the action, the amount mapping and the input schema.
| Code | Cause | What to do |
|---|---|---|
TOOL_REAUTHORIZATION_REQUIRED (denied) | The binding changed and nobody re-authorized it yet. The tool is hidden from agents. | An owner or admin reviews the tool and clicks Review & re-authorize on Tools & MCP servers. |
UPSTREAM_CHANGED (denied) | The binding was re-authorized after the decision (also after a change that was reverted), or the tool's server, URL, upstream tool or action differs from the decision. | The approval can never run. The agent calls again: the identical call closes the old action as superseded and gets a new decision. |
BINDING_CHANGED (409, in the dashboard) | While you authorized a tool, someone changed it. Nothing was authorized. | Reload, review the tool as it is now, and authorize again. |
An approval given under an earlier binding is never executed, even after the change is undone: undoing a change is itself a change that needs re-authorization.
The action was superseded
An open action (waiting for approval, or allowed but not yet executed) is closed as expired with code SUPERSEDED when the agent repeats the identical call after something it was decided on changed: the tool's binding, the delegation (revoked or expired), the organization principal, or, for calls allowed without approval, the active policy version, the tool's exposed name or its amount mapping. The repeated call gets a new decision.
Actions are also superseded without a retry: when the organization principal is replaced, and when an owner or admin rolls back or stops a policy with the option to close open actions. A person-approved action is superseded only when it can provably never run (the tool was re-authorized with another binding, or the principal was replaced).
The delegation was revoked after the approval
A person-approved action is not superseded when its delegation is revoked or expires. Every identical retry is refused (denied, VERIFICATION_FAILED) until the action expires or an owner or admin cancels it with Cancel this action on the action page (signed with the principal key in that browser). A cancellation issues a receipt.
POLICY_CHANGED
Symptom. A call that was allowed without approval is refused with status: "denied" and code POLICY_CHANGED: "the agent's policy changed after this allow decision and the policy now in force does not allow the call; retry: the identical call is decided by the policy now in force". Nothing was consumed.
Cause. Between the decision and the execution, the agent's policy changed. Right before executing an allow decision, the Gateway compares it with the policy in force:
- same active version: it executes;
- another active version: it evaluates the recorded call again and executes only if the new version also allows it;
- the agent was moved to another policy, or its policy has no active version: refused.
An emergency stop or a rollback whose option closes approved calls too also refuses calls decided under the replaced versions, including ones a person approved: an attempt to run one before K-Block has closed it is refused POLICY_CHANGED, and the action is closed as superseded.
Fix. Have the agent repeat the call: the identical call is decided by the policy now in force (and may need an approval).
OBSERVE_ENDED is the same check for a call an observe window allowed: the window has ended, so the call is not executed. Retrying decides it under enforcement.
The approval expired
Every approval request and every allowed or approved action has an expiry. It is the shortest of: the deciding rule's approval_ttl_seconds, or else the organization's Default approval lifetime (seconds) under Settings (60 to 2,592,000 seconds; 86,400 by default); the time left on the delegation; and, for a call relaxed by observe, the time left on the window.
Code (status expired) | Cause |
|---|---|
APPROVAL_EXPIRED | Nobody decided the request before it expired. |
TASK_EXPIRED | The call was approved (or allowed), but the agent did not repeat it before it expired. The approval request itself stays Approved; its page shows TASK_EXPIRED below the decision. |
SUPERSEDED | Closed because something changed; see The action was superseded. |
Nothing was executed and no receipt is issued for an expired action. K-Block marks a request expired within about 15 seconds after its expiry, and the Gateway also checks the expiry when the agent resumes, so a lapsed approval never runs. Until then, the Pending tab of Approvals can list a request that has already lapsed, marked "expired …".
Fix. Have the agent call again to create a new request. If requests expire before anyone can act, raise the rule's approval_ttl_seconds or the organization's default, and check that the delegation does not expire sooner. Make sure the agent resumes after the approval: an approved call runs only when the agent repeats it.