vercel/ai · error
Video generation did not complete after webhook notification
Error message
Video generation did not complete after webhook notification.
What it means
After a webhook notification arrived, the subsequent (or final) doStatus call still did not report a completed (or failed) status, so the flow cannot produce a result. The SDK throws because it cannot reconcile the webhook event with the provider's status endpoint.
Source
Thrown at packages/ai/src/generate-video/generate-video.ts:598
if (statusResult.providerMetadata != null) {
operationProviderMetadata ??= {};
mergeProviderMetadata(
operationProviderMetadata,
statusResult.providerMetadata,
);
}
if (statusResult.status === 'completed') {
return {
videos: statusResult.videos,
warnings: allWarnings,
providerMetadata: operationProviderMetadata,
response: statusResult.response,
};
}
if (webhookReceived != null) {
throw new Error(
'Video generation did not complete after webhook notification.',
);
}
}
}
async function waitForWebhook({
received,
timeoutMs,
abortSignal,
delay,
}: {
received: PromiseLike<Experimental_VideoModelV4OperationWebhook>;
timeoutMs: number;
abortSignal?: AbortSignal;
delay: (
delayInMs: number,
options?: { abortSignal?: AbortSignal },View on GitHub (pinned to 69428b1f8b)
Solutions
- Re-check status after a short delay with experimental_getVideoStatus instead of assuming failure.
- Verify the webhookUrl endpoint is correct and the provider's webhook semantics match the SDK's expectations.
- Increase tolerance/retry the status check; treat it as transient if the provider is eventually consistent.
- If reproducible, report to the provider/SDK since the webhook and status endpoints disagree.
Example fix
// before
const { video } = await op; // may throw after webhook
// after
try {
const { video } = await op;
} catch (e) {
if (e.message.includes('webhook')) {
const status = await experimental_getVideoStatus({ model, operation: op.operation }); // re-poll
}
} Defensive patterns
Strategy: retry
Validate before calling
// ensure webhookUrl is a publicly reachable https endpoint before starting
new URL(webhookUrl); if (!webhookUrl.startsWith('https://')) throw new Error('webhookUrl must be public https'); Type guard
null
Try / catch
try {
const { video } = await op;
} catch (e) {
if (e.message.includes('webhook')) {
// webhook arrived but status disagreed; re-poll before giving up
const status = await experimental_getVideoStatus({ model, operation: op.operation });
}
} Prevention
- Use an eventually-consistent-friendly re-poll after webhooks.
- Verify webhook endpoint reachability and provider webhook registration.
- Check the provider's webhook semantics (progress vs completion events).
- Keep provider SDK/package versions up to date.
When it happens
Trigger: executeStartStatusFlow with webhookUrl configured: waitForWebhook resolved (webhookReceived != null) but the polled statusResult still indicates a non-terminal/non-success state.
Common situations: Provider sends webhook events out of order or before its status API is consistent; webhook payload parsed but status endpoint lags; provider bug where webhook signals progress rather than completion; network caching of stale status responses.
Related errors
- statusResult.error
- Video model ${model.modelId} does not implement doGenerate o
- No video generated.
- Video generation timed out after ${timeoutMs}ms.
- Video model ${model.modelId} does not implement doStatus.
AI-assisted analysis of vercel/ai@69428b1f8b (2026-08-30).
Data as JSON: /api/errors/f8b4952240a387ce.
Report an issue: GitHub.