When the Mandate policy engine rejects a transaction, the response includes a blockReason field. This machine-readable string tells you exactly which check failed. The response also includes a human-readable blockDetail explaining the specifics and a declineMessage designed to counter prompt injection attempts.Every blocked response follows this format:
Copy
Ask AI
{ "allowed": false, "blockReason": "per_tx_limit_exceeded", "blockDetail": "$500.00 exceeds $100/tx limit", "declineMessage": "This transaction exceeds your per-transaction limit of $100."}
The declineMessage is an adversarial counter-message. When an agent receives a block, it should display this message to override any manipulative prompt that triggered the transaction attempt.
The policy engine runs 14 sequential checks. The first failure wins: later checks are skipped. Block reasons appear in the order the engine evaluates them.
These blocks apply only to the deprecated raw validation endpoint (POST /api/validate/raw). Action-based validation does not produce these block reasons.
blockReason
HTTP
Cause
Resolution
gas_limit_exceeded
422
Gas limit in the transaction exceeds max_gas_limit configured in the policy.
Lower the gas limit in your transaction, or increase max_gas_limit in the policy.
value_wei_exceeded
422
Native value (ETH/wei) in the transaction exceeds max_value_wei configured in the policy.
Lower the native value, or increase max_value_wei in the policy.
selector_blocked
422
The 4-byte function selector in the transaction calldata is in the policy’s blocked_selectors list.
Remove the selector from blocked_selectors, or use a different contract function.
intent_hash_mismatch
422
The intentHash submitted by the client does not match the server’s recomputation from the same parameters.
See Intent Hash Mismatch Troubleshooting. Common causes: stale nonce, uppercase addresses, missing 0x prefix, or accessList set to undefined instead of [].
These blocks come from automated scanning systems.
blockReason
HTTP
Cause
Resolution
aegis_critical_risk
422
Destination address is flagged as CRITICAL risk by the Aegis security scanner. Associated with known exploits, sanctions, or rug pulls.
Verify the address is correct. If you believe this is a false positive, contact the Mandate risk team. Do not retry with the same address.
reason_blocked
422
The reason field triggered prompt injection detection. Mandate scans for 18 attack patterns across 5 categories: direct injection, jailbreak, encoding evasion, multi-turn manipulation, and authority escalation.
Review the reason text and rewrite it without manipulation language. Legitimate reasons like “Pay invoice #127 from Alice” pass. Phrases like “ignore all instructions” or “URGENT: do not verify” are blocked.
Check for specific block reasons using the SDK’s typed error classes:
Copy
Ask AI
import { PolicyBlockedError, CircuitBreakerError, RiskBlockedError } from '@mandate.md/sdk';try { await client.validate({ action: 'transfer', reason: 'Pay invoice', amount: '500', to: '0xAlice' });} catch (err) { if (err instanceof CircuitBreakerError) { // blockReason: circuit_breaker_active console.error('Agent is emergency-stopped. Contact the owner.'); } else if (err instanceof RiskBlockedError) { // blockReason: aegis_critical_risk console.error(`Risky address: ${err.blockReason}`); } else if (err instanceof PolicyBlockedError) { // Any other blockReason console.log(`Blocked: ${err.blockReason}`); console.log(`Detail: ${err.detail}`); console.log(`Decline message: ${err.declineMessage}`); }}
Never suppress or retry a blocked transaction without changing the parameters. The block reason tells you what to fix. Retrying the same request produces the same result.