AI Product Tools
Troubleshooting

Provider errors

Every exact message OpenAI, Google Gemini, Anthropic Claude and OpenRouter failures can show, what causes each one, and how to fix it.

Every feature that calls AI, the six bulk generators, the Product Editor, the product metabox, Content Templates, Automation Jobs and the AI Shop Assistant, goes through the same four provider clients and turns every possible failure into one of a small, fixed set of plain-English messages. Learn this one list and you can read an error from anywhere in the plugin.

The message always names the provider

A failure always reads "{Provider} rejected the saved API key", "{Provider} is limiting requests right now", and so on. If your default provider is Google Gemini, the same underlying problem reads "Gemini..." instead of "OpenAI...". The cause and fix are identical either way.

Before you start

  • These messages come from the AI provider itself, or from this plugin's own local checks before a request is even sent. None of them come from a credit or allowance system: the plugin is BYOK and never meters your usage.
  • A run-wide failure (an invalid key, no quota, an outage, a firewall block) stops the rest of a batch on purpose, because every remaining item would fail identically. A failure tied to one item (a safety filter, a cut-off answer, an unreadable image) only fails that row; the rest of the batch keeps going.
  • The plugin already retries one transient failure automatically, after the provider's own Retry-After header or about 1.5 seconds by default. If the provider asks for a longer wait than that, up to 10 seconds, the plugin waits once and retries; a wait request longer than 10 seconds skips the retry and shows the error right away instead of holding the request open. You do not need to manually retry a 429 the moment you see it.

Where a key or setup problem shows up

No key saved

If no AI provider has a saved key at all, the page tells you before you even try to generate: an amber AI provider not configured banner appears above the product list, the Provider picker has nothing to select, and Generate Bulk stays disabled.

Bulk description generator showing an amber AI provider not configured banner with an Open plugin settings link, an empty Provider picker, and a disabled Generate Bulk button
No key means no generation, on any plan, for any generator.

If at least one provider still has a key but the one this screen would use does not, generating anyway (or a scheduled job that names that provider specifically) fails with the named version instead: "No {Provider} API key is saved. Add one in Settings > Connectors or AI Product Tools > API." (see the reference table below).

A key that looks wrong

Typing a key in the wrong shape is caught before the plugin ever contacts the provider: Claude keys must start with sk-ant-, OpenRouter keys must be at least 20 characters. OpenAI and Gemini accept any non-empty string locally and let the provider itself reject a bad one.

Settings Connection page showing an error toast reading this does not look like a valid Claude API key
Caught locally, instantly, before any request leaves your site.

A key the provider rejects

Saving a key that is the right shape but revoked, rotated, or mistyped fails only when you click Save Settings, the plugin re-validates every changed key live:

Error toast reading Gemini rejected this API key, check that you copied the whole key and that it is still active
A rejected key blocks the whole settings save, not just that field. See Connection settings for the full save flow.

A provider hiccup during save looks different on purpose

If the provider itself is briefly unreachable or overloaded at the exact moment you save a new key, the message says so, it never claims the key is invalid when the real cause is a transient outage:

Error toast reading Gemini is overloaded or unavailable right now, try again in a few minutes, shown after saving a correctly formatted key
Compare the wording with the rejected-key toast above: this one asks you to wait, not to re-copy the key.

The full reference

Every reason the plugin's provider layer can produce, in the exact wording it shows (the provider name fills in %s):

You seeWhat it meansFix
"No %s API key is saved. Add one in Settings > Connectors or AI Product Tools > API."Nothing saved for the provider this screen needsConnection settings: add a key
"This does not look like a valid %s API key. Check that you copied the whole key from the provider's dashboard."Obviously malformed: a truncated paste, or a Claude/OpenRouter key failing the local shape checkRe-copy the full key
"%s rejected the saved API key. Update it in Local plugin key." (or "...in WordPress Connectors" when that is the key's source)The provider revoked, rotated, or never recognized this keyPaste a fresh key and save again
"Your %s API key does not have access to this model or action."The key is valid but scoped away from the model or endpoint you asked forUse a key with full access, or pick a model the key can reach
"%s does not offer the selected model. Choose another model."The model was retired, renamed, or never existedPick a different model from the dropdown
"Your %s account has no quota or credit left. Check your billing with the provider."No balance, or a plan limit reached, at the providerAdd credit or billing on the provider's own dashboard
"%s is limiting requests right now. Try again in a minute."The provider's own per-minute rate limit, separate from this plugin's own internal 700-requests-per-5-minutes capWait, lower Pause between requests in Connection settings, or batch fewer items
"%s is overloaded or unavailable right now. Try again in a few minutes."A provider-side outage or capacity problemWait and retry; the plugin already retried once automatically
"Could not reach %s. Check the site's connection and whether a firewall or security plugin blocks outbound requests, then try again."Either a genuine connection timeout, or a DNS failure, a refused connection, or a security plugin returning a block page instead of a real responseCheck your host's firewall rules and allow outbound requests to the provider's domain
"%s declined to answer because of its safety filters."The provider's own safety system refused the prompt or the product contentReword the product content or your custom instructions, or try a different model
"%s stopped before finishing the answer."The model hit its output token limit before finishingAsk for a shorter result, or pick a model with a larger output limit
"The request was too large for %s. Shorten the product content or choose a model with a larger context window."Your prompt plus the product data is bigger than the model's context windowShorten the product description or attributes being sent, or switch to a bigger-context model
"The image could not be loaded to send to %s. Check that the file exists and that the site can read it."The image alt generator's source image is missing, unreadable, over 20 MB, or not a recognized image formatFix or replace the product image
"AI features are turned off on this site, so %s cannot be used. Set WP_AI_SUPPORT to true to turn them back on."WordPress 7.0's own site-wide AI switch (wp_supports_ai()) is offA developer removes the filter, or sets the WP_AI_SUPPORT constant to true
"%s is not a supported AI provider. Choose OpenAI, Gemini, Claude or OpenRouter in the settings."A corrupted or leftover provider value, not reachable from the normal screensRe-save Settings with a real provider selected
"%s could not process the request. Details were logged for troubleshooting."A catch-all: an unrecognized response shape, invalid JSON, or (only on the newer content-structure path) a rejected structured-output request that the plugin already retried once automatically with structured output turned offUsually transient; retry. Check the PHP error log if it repeats

A rate limit is not the same as no quota

"Limiting requests right now" means you are sending requests too fast; "no quota or credit left" means your account itself has nothing left to spend. The exact-sounding 429 status from several providers can mean either one, and the plugin reads the provider's own error body to tell them apart so you do not chase the wrong fix.

Every reason, as it actually looks

Generation stopped banner reading OpenAI rejected the saved API key, update it in Local plugin key
auth_invalid_key during generation (compare with the Settings-save version earlier on this page).
Error toast reading Belt, your OpenAI API key does not have access to this model or action
auth_forbidden: the key works, but not for this model or action.
Error toast reading Belt, OpenAI does not offer the selected model, choose another model
model_not_found.
Error toast reading Belt, OpenAI is limiting requests right now, try again in a minute
rate_limited.
Error toast reading Belt, your OpenAI account has no quota or credit left, check your billing with the provider
quota_exhausted, worded quite differently from rate_limited despite both often arriving as the same HTTP status.
Error toast reading Belt, OpenAI is overloaded or unavailable right now, try again in a few minutes
provider_unavailable.
Error toast reading Belt, could not reach OpenAI, check the site's connection and whether a firewall or security plugin blocks outbound requests
network_timeout. network_error (shown earlier on this page, the firewall/WAF case) reads identically.
Error toast reading Belt, the request was too large for OpenAI, shorten the product content or choose a model with a larger context window
request_too_large.
Error toast reading Belt, OpenAI could not process the request, details were logged for troubleshooting
malformed_response. invalid_schema_request and bad_request share this same generic sentence.

A safety filter or a cut-off answer only stops that one item

Unlike a key or connection problem, a safety refusal or a truncated answer is specific to one product's content or one model's limits, so only that row fails:

Bulk image alt generator showing OpenAI declined to answer because of its safety filters for one image, with a Needs Review badge
A safety refusal on the Bulk Image Alt Generator. Only this image failed; other selected images are unaffected.
Bulk description generator row showing the model stopped before finishing the answer
The model ran out of output length before it finished.

A run-wide failure stops the whole batch

An invalid key, no quota, an outage, or a firewall block will fail identically for every remaining product, so the plugin stops the batch instead of repeating the same failure for each one:

Error toast and page banner reading Belt, could not reach OpenAI, check the site's connection and whether a firewall or security plugin blocks outbound requests
A security plugin or hosting firewall intercepting the request looks exactly like this: a connection problem, not an invalid key.

Re-select only the products that did not run and generate again once the underlying problem (the key, the outage, the firewall rule) is fixed. Nothing is lost by not having attempted the skipped items, since they would have failed the same way.

OpenRouter can fail mid-generation even on a successful response

Because OpenRouter proxies other providers, a failure can arrive two ways on the exact same request: a normal error response, or an outer success that hides a failure inside the one answer it chose:

Generation stopped banner reading OpenRouter is overloaded or unavailable right now, with OpenRouter selected as the provider and Auto Best Available Free as the model
The underlying model died mid-stream after OpenRouter had already returned a success. The plugin still resolves this to an accurate, readable reason instead of a blank or generic failure.

You do not need to tell these two shapes apart yourself: whichever way OpenRouter reports the failure, you still get one of the plain messages from the reference table above.

Adding a custom OpenRouter model that does not exist

OpenRouter's Model picker includes an Add Custom Model option for typing a model id OpenRouter does not already list. This check runs the moment you try to add it, before it is ever available to select for a generation, so it is not one of the reasons in the reference table above:

Add OpenRouter model dialog showing the slug openai definitely not a real model xyz and an error reading This model is not currently available on OpenRouter
A typo'd or retired model id is caught here, before it ever reaches a generation run.
You seeCauseFix
"This model is not currently available on OpenRouter."The slug does not match anything in OpenRouter's current model catalogCheck the spelling against OpenRouter's own model list, or pick one of the suggested models instead
"OpenRouter model validation is temporarily unavailable. Please try again."OpenRouter's model catalog itself could not be reached at that momentWait a moment and try adding the model again

Automation Jobs pause instead of burning through every product

A scheduled job behaves the same way a manual run does: a run-wide reason pauses the job rather than letting it fail through every remaining product one at a time.

Automation Jobs list showing a Title refresh job with a Paused status badge, a warning icon next to its name, and 0 of 3 products processed
This job paused before touching any product: a dead key is detected on the very first attempt.

Click the warning icon next to the job's name (or View error logs) to open its log, where the recorded reason appears as a plain-text warning entry:

Job Logs panel for Title refresh (demo) showing a Warning entry reading OpenAI rejected the saved API key, update it in Local plugin key, tagged Type Provider and Provider openai
The exact same sentence a manual run would have shown, recorded against the job instead of a page banner.

Fix the underlying provider problem in Connection settings, then resume or retry the job. See Monitoring a job for pause, resume, and retry controls.

What a shopper sees is never the raw error

A provider failure during a chat conversation is never shown to the shopper as a raw technical message. A key or setup problem (an invalid key, a missing one, an unsupported model) reads as a short, generic configuration notice with a Retry button; depending on your Error Display settings (AI Shop Assistant → General), any other failure shows either a fuller generic apology, your own custom message, or the same plain sentence from the table above, redacted of anything sensitive:

Storefront chat widget on the Belt product page showing a shopper's question answered with Configuration issue, please contact admin and a Retry button, after the configured AI provider rejected the API key behind the scenes
The shopper never sees 'invalid API key' or any other internal detail, only a short notice and a Retry button. The conversation is still queued for you to follow up on.

See Shop assistant issues for the exact wording of each option and what a queued message looks like on your side.

Reference: where each check happens

CheckWhen it runsNeeds a network call?
Key missing / key formatBefore any request is builtNo
AI features are turned off (WP_AI_SUPPORT)Before any request, on WordPress 7.0+ onlyNo
Everything else in the table aboveAfter the request reaches the provider (or its transport fails)Yes

Troubleshooting