Skip to content

How Blocking Works

When a WordPress plugin calls wp_ai_client_prompt(), AI Valve evaluates the request before it reaches the AI provider. If the request violates any policy, it is blocked immediately — no tokens are consumed.

  1. AI Valve’s PolicyEngine::evaluate() returns false.
  2. RequestInterceptor returns a WP_Error with code prompt_prevented and a message containing the denial reason.
  3. The calling plugin receives this WP_Error instead of an AI response.
  4. The request is logged in the AI Valve log with a status of denied:<reason>.

The calling plugin is responsible for handling the WP_Error gracefully (e.g. showing a fallback message or silently skipping the AI feature).

Policy checks run in order. The first failing check blocks the request:

#ReasonMeaning
1soderlind_aivalve_disabledThe master switch is off — all AI requests are blocked.
2plugin_deniedThe plugin’s per-plugin policy is set to Deny.
3context_deniedThe current execution context (admin, frontend, cron, REST, AJAX, CLI) is not in the allowed list.
4plugin_daily_budget_exceededThe plugin has used all of its per-plugin daily token budget.
5plugin_monthly_budget_exceededThe plugin has used all of its per-plugin monthly token budget.
6global_daily_budget_exceededThe site-wide daily token budget has been reached.
7global_monthly_budget_exceededThe site-wide monthly token budget has been reached.
  • Daily budgets reset at midnight (server time) each day.
  • Monthly budgets reset on the first day of each calendar month.

A limit of 0 means unlimited — no cap is enforced.

Go to Settings → AI Valve → Logs and filter by Status → Denied. Each denied row shows the full denial reason, the calling plugin, and the execution context.

The Dashboard tab also shows denied requests in the context breakdown table.

When Guard Abilities API is enabled in Settings, AI Valve also evaluates policy on the WordPress Abilities API execution lifecycle:

  1. On wp_pre_execute_ability, the ability namespace (the part before the slash in namespace/ability-name) is used as the policy subject and passed through the same PolicyEngine.
  2. If policy denies it, execution is short-circuited before input validation, permission checks, or the ability callback run — no callback side effects occur.
  3. The caller receives a WP_Error with code ability_prevented (HTTP 403), and the denial is logged with provider_id = wp-abilities and the ability name in the capability column.

The same seven denial reason codes apply. Because the namespace is the policy subject, per-plugin allow/deny rules and the aivalve_plugin_policy filter govern abilities too. Token budgets only affect an ability namespace if that namespace also consumed tokens through the AI connector.

This guard is off by default and independent of the AI connector, so it works even when wp_ai_client_prompt() is unavailable.

If your plugin calls wp_ai_client_prompt(), always check for WP_Error:

$result = wp_ai_client_prompt( $prompt );
if ( is_wp_error( $result ) ) {
// AI request was blocked or failed.
// $result->get_error_code() → 'prompt_prevented'
// $result->get_error_message() → e.g. 'plugin_daily_budget_exceeded'
return;
}
// Use $result normally.

This ensures your plugin degrades gracefully when AI Valve (or any other gating plugin) blocks the request.