Templates get you a working first prompt. They don't tell you why your second attempt came out jittery, why a reference image you provided got ignored in favor of one you didn't expect, or why a subject's hand briefly turned into something with the wrong number of fingers for two frames. Those failures have specific, identifiable causes, and once you can recognize the pattern, fixing them stops being trial and error. That's the part worth writing down instead of another copy-paste template list — there are already plenty of those.
Jitter and artifacts: usually a camera-verb collision, not bad luck
The single most common failure pattern I kept running into was visual jitter or subtle warping during motion — and it almost always traced back to the same root cause: stacking multiple, conflicting camera movement instructions in one shot. A prompt describing a handheld shake, an orbit, a zoom, and a whip pan all in the same few seconds isn't giving the model four compatible instructions — it's giving it four movements that can't all resolve into one coherent camera path, and the model's attempt to reconcile them is what shows up as artifacts.
The fix is committing to one dominant camera movement per shot. If you genuinely need multiple distinct movements, that's a multi-shot prompt with explicit shot breaks, not one shot carrying all of them at once:
Bad (stacked, conflicting):
Handheld tracking shot with a slow zoom and subtle orbit around the subject, quick whip pan at the end.
Better (one dominant move, split into shots):
Shot 1: Static medium shot, subject enters frame from the left.
Shot 2: Slow handheld push-in toward the subject's face as they turn.

Wrong reference driving the scene: an assignment problem, not a model problem
If you supply more than one reference asset — an image for character appearance, another for environment, a video for camera motion — and don't explicitly say what each one is for, the model has to guess which reference controls which part of the output, and it doesn't always guess the way you expected. This shows up as a generated scene that pulls color palette from the wrong image, or motion that doesn't match the reference video you actually wanted followed.
The fix is mechanical: label every reference's job explicitly rather than assuming order or context implies it.
Ambiguous:
[image1] [image2] [video1] — generate a scene with this character in this setting.
Explicit:
@image1 as character reference (face, outfit, hair)
@image2 as environment reference (lighting, color palette, set dressing)
@video1 as camera movement and pacing reference only — do not use its background
That last line — explicitly telling the model what a reference should not drive — is worth using deliberately whenever a reference asset has one property you want and others you don't.
Audio that silently does nothing
I covered this one in more depth in an earlier piece on Seedance 2.0 specifically, but it's common enough to repeat here: audio submitted alone, or text plus audio with no visual reference at all, doesn't generate anything — every job needs a visual anchor (text-to-video, image-to-video, or a reference video), with audio layered on top of one of those rather than standing alone. If a job silently fails or produces nothing usable, checking whether you actually gave it a visual anchor is worth doing before assuming the prompt wording is the problem.
Camera description and subject action, kept separate
A subtler failure mode: writing camera movement and subject movement as one blended description, which makes it ambiguous which parts of the described motion belong to the camera versus the subject. "The camera follows the dancer as she spins toward the light" mixes a camera instruction (follows) with a subject instruction (spins) with a spatial detail (toward the light) in one clause. Separating them into distinct lines — what the camera does, then what the subject does — tends to produce cleaner motion, because the model isn't parsing one sentence to extract two different kinds of instructions.
Vague adjective stacks instead of concrete action
The other recurring pattern behind flat, generic-looking output: prompts loaded with mood adjectives (cinematic, dramatic, atmospheric, premium) but thin on what specifically happens. A model has a lot to infer from "cinematic dramatic lighting, premium atmosphere" and comparatively little to work with, versus a prompt naming a specific subject, a specific action, and a specific environment, with style descriptors added on top rather than substituted in for the concrete details. Style words are seasoning, not the actual recipe.
Using negative instructions as a real prompting lever
Beyond describing what you want, explicitly stating what shouldn't appear is worth using deliberately rather than as an afterthought — excluding duplicated limbs, unwanted on-screen text, background music bleeding in from a reference clip, or a reference's visual style leaking into parts of the scene it shouldn't touch. Treating exclusions as a first-class part of the prompt, not a fallback for when something already went wrong, catches a meaningful share of the failure modes above before you even get to a first generation.
The actual debugging method: change one layer at a time
When a generation comes back wrong, the instinct is to rewrite the whole prompt. The more effective approach is isolating a single variable per attempt — if framing is wrong but the action is right, adjust only the camera description and leave subject and action untouched; if motion feels unstable, adjust only the camera movement instruction. Changing multiple things at once after a failed generation makes it impossible to tell which change actually fixed anything, which means you learn nothing for the next prompt.
This is straightforward enough to script if you're iterating through an API rather than a UI:
// prompt-variant-tester.js — holds everything constant except one variable per run,
// so a fix (or a non-fix) is actually attributable to a specific change
async function submitJob(baseURL, apiKey, prompt, model) {
const res = await fetch(`${baseURL}/video/generations`, {
method: "POST",
headers: { "Content-Type": "application/json", Authorization: `Bearer ${apiKey}` },
body: JSON.stringify({ model, prompt, duration: "auto" }),
});
const { job_id } = await res.json();
return job_id;
}
function buildPrompt({ subject, action, environment, camera }) {
return [
`Subject: ${subject}`,
`Action: ${action}`,
`Environment: ${environment}`,
`Camera: ${camera}`,
].join("\n");
}
async function testCameraVariants(baseURL, apiKey, model, base, cameraOptions) {
const jobs = [];
for (const camera of cameraOptions) {
const prompt = buildPrompt({ ...base, camera });
const jobId = await submitJob(baseURL, apiKey, prompt, model);
jobs.push({ camera, jobId });
console.log(`Submitted with camera="${camera}" -> job ${jobId}`);
}
return jobs; // poll each job_id separately, compare outputs side by side
}
// Everything held constant except the camera description across three runs
testCameraVariants(
process.env.SEEDANCE_BASE_URL,
process.env.SEEDANCE_API_KEY,
"seedance-2.0",
{
subject: "a ceramic mug on a wooden table",
action: "steam rising slowly from the mug",
environment: "quiet kitchen, morning light through a window",
},
[
"static medium shot, no movement",
"slow push-in toward the mug",
"gentle handheld motion, subtle drift",
]
);
Running three controlled variants that differ only in the camera line, and comparing them side by side, tells you specifically whether the camera description was the actual source of a jitter problem — rather than rewriting the whole prompt and being unable to say which change did what.
One version-awareness note before you commit to specific limits
Reference asset limits, maximum duration, and supported input counts have changed between Seedance versions and continue to shift — treat any specific number you read (including counts I've mentioned in other pieces) as something to verify against the current documentation for the exact model version you're calling, rather than assuming it's carried over unchanged from an earlier release.
Where this fits with actually calling the API
None of the above requires a specific gateway — it's model behavior, not infrastructure. If you're already routing other model calls through one key and want Seedance access alongside them rather than a separate account, [RouteAI](Running three controlled variants that differ only in the camera line, and comparing them side by side, tells you specifically whether the camera description was the actual source of a jitter problem — rather than rewriting the whole prompt and being unable to say which change did what.
One version-awareness note before you commit to specific limits
Reference asset limits, maximum duration, and supported input counts have changed between Seedance versions and continue to shift — treat any specific number you read (including counts I've mentioned in other pieces) as something to verify against the current documentation for the exact model version you're calling, rather than assuming it's carried over unchanged from an earlier release.
Where this fits with actually calling the API
None of the above requires a specific gateway — it's model behavior, not infrastructure. If you're already routing other model calls through one key and want Seedance access alongside them rather than a separate account, RouteAI lists Seedance in its catalog; that's a routing convenience, not something that changes any of the prompting behavior described here.
TL;DR: Most Seedance prompt failures trace back to a handful of specific, recognizable causes — stacked conflicting camera verbs (jitter), unlabeled multi-reference assignment (wrong reference driving the scene), blended camera/subject descriptions, and vague adjective stacking instead of concrete action. Changing one variable per attempt instead of rewriting the whole prompt is what actually turns failures into fixes instead of another reroll.
Website: https://www.fastrouteai.com) lists Seedance in its catalog; that's a routing convenience, not something that changes any of the prompting behavior described here.
TL;DR: Most Seedance prompt failures trace back to a handful of specific, recognizable causes — stacked conflicting camera verbs (jitter), unlabeled multi-reference assignment (wrong reference driving the scene), blended camera/subject descriptions, and vague adjective stacking instead of concrete action. Changing one variable per attempt instead of rewriting the whole prompt is what actually turns failures into fixes instead of another reroll.
Website: https://www.fastrouteai.com
Top comments (0)