blog/guides·Sep 9, 2026·6 min·by the eroq team

Why my render was blocked — reading the content policy error

What content_blocked means, why a blocked request costs nothing, which engines are moderated upstream, and how to tell a refusal from a failure.


You pressed generate and got a sentence back instead of a clip. The engine declined this prompt. Rephrase it and retry — you have not been charged. It is a short message and it does not tell you which of four quite different situations you are in. This article is that missing paragraph, without the drama.

What the error actually is

A block has one code, content_blocked, and it reaches you from the two surfaces that call a rendering engine — images and video — in the same shape.

On images the call answers HTTP 422 with the standard error envelope:

{
  "error": {
    "message": "The engine declined this prompt. Rephrase it and retry — you have not been charged.",
    "type": "invalid_request_error",
    "code": "content_blocked"
  }
}

Video is asynchronous, so the block arrives when you poll the job rather than when you submit it:

{
  "id": "…",
  "object": "video.generation",
  "status": "failed",
  "model": "seedance-1-pro",
  "duration": "5s",
  "error": { "type": "invalid_request_error", "code": "content_blocked" },
  "usage": { "credits_spent": 0, "credits_remaining": 4820 }
}

Note the type. A block is an invalid_request_error — a statement about the request — while an engine that tried and failed returns upstream_error. That single field is the fastest way to sort a refusal from a bad roll, and a video.generation.failed webhook carries the same code if you are listening for one.

It is never charged, but you may see two rows

credits_spent is zero and your balance ends where it started. The mechanism underneath is worth knowing, because it surprises people reading their ledger.

Video charges when you submit and refunds when the job resolves badly, so a blocked clip produces a charge row and a matching negative refund row in the same minute. They net to zero. Images charge for the batch upfront and refund each take that comes back empty. Either way you pay for delivered work only — but the ledger tells the truth about the sequence rather than hiding it. There is a full walkthrough in how to read your usage ledger.

The three limits that never move

Some prompts are refused everywhere on eroq, permanently, and no rewrite changes that. They are written down in the acceptable-use policy and they are short.

Any sexual content involving minors — real, fictional, stylized or implied. Real identifiable people without consent, which covers deepfakes and impersonation of public figures. Anything illegal, plus harassment. Enforcement here is at the account level, not just the request, so this is not a filter to route around.

If your prompt is in this territory, the block is the correct outcome and the article ends for you here. Everything below is about the other cases, which are far more common.

Where the wall actually sits on each surface

This is the case most people are in, and it is a routing problem rather than a policy problem.

Every video engine except one is moderated by its own provider, upstream of eroq — Seedance 2.5, Seedance 1.0 Pro and Lite, Kling, Hailuo and Veo all render SFW work only, and the refusal is theirs. Motion One · Wan is the uncensored video engine, it is available on every account including the free tier, and it is the answer whenever the problem is that your scene is mature rather than that it is prohibited.

Images, chat and voice do not have that split — they are uncensored within the same written policy, on every model. Images still render through an engine that can decline a specific prompt, so content_blocked is a thing you will occasionally meet there, and when you do it is either one of the three hard limits above or a false positive on a word. Chat and voice have no engine-side content gate of this kind at all; the hard limits are enforced at the account level instead.

Put plainly: a mature prompt on Kling is not a policy failure, it is a shot pointed at the wrong engine, and no amount of rephrasing will move it. Switch engine. There is a wider view of that boundary in uncensored AI.

Telling a refusal from a failure

Four states look similar in the interface and behave completely differently. Why AI video renders fail covers the whole taxonomy; the short version for triage:

  • content_blocked — a content decision. Retrying reproduces it exactly. Rewrite, or change engine.
  • generation_failed — the engine accepted the job and returned nothing. This is the dice. Retry.
  • generation_timeout — the render never came back. A job stuck past ten minutes is failed and refunded the first time you poll it.
  • The pre-flight refusals, which are not blocks at all — 403 plan_required (the engine is above your plan), 503 model_unavailable (that engine is not open for business yet), 402 insufficient_credits (empty wallet), 403 role_forbidden (your workspace role cannot spend credits) and 429 rate_limit_exceeded (with a Retry-After header telling you how many seconds to wait). All of these are decided before the job is queued, so nothing is billed and there is nothing to refund.

Retry logic worth writing is one line long: never retry content_blocked, retry the failure and the timeout, and surface everything else to a human.

When it is a false positive

The annoying case: you wrote something innocent and a word tripped a filter. Filters read nouns, not intent, so the fix is to describe the picture rather than the event — name the shot, the light and the wardrobe instead of the act, and drop any real person's name. The full rewrite drill lives in the article linked above and is worth bookmarking.

One more diagnostic that costs nothing. Run the same prompt on Motion One. If it renders there and was blocked on a premium engine, you learned that the prompt is fine and the provider is strict. If Motion One blocks it too, you are much closer to one of the three hard limits than you thought.

Open the video studio and try the shot again on the right engine.

FAQ

Am I charged when a render is blocked?

No. Blocked work never costs you credits — video charges at submission and immediately refunds when the job comes back blocked, images refund each empty take, and the response reports credits_spent as zero. If your balance moved, look for the matching negative row in the request log before assuming otherwise.

Why does the same prompt render on one engine and not another?

Because every video engine except Motion One is moderated by its upstream provider and serves SFW work only. Motion One runs on an uncensored deployment and is the engine for mature fiction, within the written policy. Images, chat and voice are uncensored on every model, so the split only affects video.

Does a blocked prompt get my account flagged?

The hard limits — minors, real identifiable people, anything illegal — are enforced at the account level rather than per request, so those matter. An ordinary false positive on a keyword is not that, and rewriting and retrying is a normal part of using the tool. If you are unsure which side of the line a project sits on, read the acceptable-use policy first.

How do I handle blocks programmatically?

Branch on the error code rather than the message text. content_blocked arrives as invalid_request_error and must never be retried, while generation_failed and generation_timeout arrive as upstream_error and are worth two attempts. Everything else — plan gates, empty wallets, rate limits — is a configuration problem that needs a person, not a loop.

Tagstroubleshootingcontent-policyerror-codesmoderation

Make this with the models behind the post — start with 50 free credits , or browse every engine and its price .