{"record":{"id":"dbb12d14c82b2ff1","repo":"vercel/ai","slug":"video-model-model-modelid-does-not-implement-do","errorCode":null,"errorMessage":"Video model ${model.modelId} does not implement doGenerate or doStart/doStatus.","messagePattern":"Video model (.+?) does not implement doGenerate or doStart/doStatus\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/ai/src/generate-video/generate-video.ts","lineNumber":314,"sourceCode":"    prompt,\n    resolvedImage,\n    normalizedFrameImages,\n    effectiveInputReferences,\n    warnings,\n  } = normalizeVideoCallInputs({ promptArg, frameImages, inputReferences });\n\n  const maxVideosPerCallWithDefault =\n    maxVideosPerCall ?? (await invokeModelMaxVideosPerCall(model)) ?? 1;\n\n  // Determine whether to use the start/status flow:\n  const hasStartStatus = model.doStart != null && model.doStatus != null;\n  const useStartStatus =\n    hasStartStatus &&\n    (poll != null || webhook != null || model.doGenerate == null);\n\n  // Validate model capabilities\n  if (model.doGenerate == null && !hasStartStatus) {\n    throw new Error(\n      `Video model ${model.modelId} does not implement doGenerate or doStart/doStatus.`,\n    );\n  }\n\n  // Warn if poll/webhook provided but model doesn't support start/status\n  if ((poll != null || webhook != null) && !hasStartStatus) {\n    logWarnings({\n      warnings: [\n        {\n          type: 'other',\n          message:\n            'poll/webhook options were provided but the model does not support doStart/doStatus. Falling back to doGenerate.',\n        },\n      ],\n      provider: model.provider,\n      model: model.modelId,\n    });\n  }","sourceCodeStart":296,"sourceCodeEnd":332,"githubUrl":"https://github.com/vercel/ai/blob/69428b1f8b037e4d118fb4853428d5c4e620493c/packages/ai/src/generate-video/generate-video.ts#L296-L332","documentation":"experimental_generateVideo requires the model to either implement doGenerate (one-shot generation) or the doStart/doStatus pair (async start-then-poll flow). If a VideoModelV* instance implements neither, the SDK throws a plain Error before calling the provider, because it has no protocol to execute the request with.","triggerScenarios":"Calling experimental_generateVideo with a custom or mock video model object that only partially implements the model interface — e.g. implements doStart but neither doGenerate nor doStatus, or is an empty/wrongly typed object cast to a video model.","commonSituations":"Hand-rolled mock models in tests missing methods; a custom provider adapter written against an older spec version; passing an image or language model by mistake; dependency version mismatch where the installed provider package predates the doStart/doStatus API.","solutions":["Use an official video model (e.g. from @ai-sdk/* provider packages) that fully implements the video model spec.","If writing a custom model, implement either doGenerate or both doStart and doStatus.","Update the provider package to a version compatible with the current video model specification.","Check that you are passing the right model object type to experimental_generateVideo."],"exampleFix":"// before\nconst model = { provider: 'custom', modelId: 'vid-1' } as VideoModel; // no methods\nawait experimental_generateVideo({ model, prompt });\n\n// after\nconst model = {\n  provider: 'custom',\n  modelId: 'vid-1',\n  doGenerate: async (options) => { /* ... */ },\n} satisfies VideoModel;\nawait experimental_generateVideo({ model, prompt });","handlingStrategy":"validation","validationCode":"function isUsableVideoModel(model: VideoModel): boolean {\n  return typeof model.doGenerate === 'function' ||\n    (typeof (model as any).doStart === 'function' && typeof (model as any).doStatus === 'function');\n}\nif (!isUsableVideoModel(model)) throw new Error('video model missing doGenerate or doStart/doStatus');","typeGuard":"function hasVideoCapability(model: unknown): model is VideoModel {\n  const m = model as VideoModel;\n  return typeof model === 'object' && model !== null &&\n    (typeof m.doGenerate === 'function' ||\n     (typeof (m as any).doStart === 'function' && typeof (m as any).doStatus === 'function'));\n}","tryCatchPattern":"try {\n  await experimental_generateVideo({ model, prompt });\n} catch (error) {\n  if (error instanceof Error && /does not implement doGenerate or doStart\\/doStatus/.test(error.message)) {\n    // swap in a compliant model or report a setup error\n  } else throw error;\n}","preventionTips":["Satisfy the VideoModel type with `satisfies` so missing methods fail at compile time.","Keep provider packages updated to the spec version the SDK expects.","Never pass untyped `as VideoModel` casts in production code."],"tags":["video","model-capability","invalid-model","configuration"],"backgroundTag":"model-capability-not-supported","analyzedSha":"69428b1f8b037e4d118fb4853428d5c4e620493c","analyzedAt":"2026-08-30T12:32:21.016Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}