yikart/AiToEarn · error · AppException
VideoUploadVidNotFound
VideoUploadVidNotFound
Error message
VideoUploadVidNotFound
What it means
downloadUrlAndUploadAsStream 在调用 uploadMaterial 成功后,期望上传结果 uploadResult.Data.Vid 存在;若火山 VOD 返回的 Result 中没有 Vid,则抛出 VideoUploadVidNotFound,表示上传链路完成但未得到媒体 ID。
Source
Thrown at project/aitoearn-backend/apps/aitoearn-ai/src/core/ai/libs/volcengine/services/upload.service.ts:230
this.logger.debug({
fileName,
fileExtension,
fileSize,
url,
}, '[downloadUrlAndUploadAsStream] 准备上传')
const uploadResult = await this.uploadMaterial({
SpaceName: this.config.spaceName,
Content: response.data,
FileSize: fileSize,
FileName: fileName,
FileExtension: fileExtension,
})
const vid = uploadResult.Data?.Vid
if (!vid) {
throw new AppException(ResponseCode.VideoUploadVidNotFound)
}
return vid
}
/**
* 批量上传 URL 并获取 vids
* 使用下载后流式上传的方式,比 URL 批量拉取更快
*/
async batchUploadUrlsAndGetVids(
urlInputs: Array<{ url: string, options?: VideoUrlInput }>,
): Promise<string[]> {
const results = await Promise.allSettled(
urlInputs.map(({ url, options }, index) =>
this.downloadUrlAndUploadAsStream(url, options)
.then((vid): UploadSuccess => ({ success: true, vid, url, index }))
.catch((error): UploadFailure => {
const errorMessage = getErrorMessage(error)View on GitHub (pinned to d3aa8bea5b)
Solutions
- 记录 uploadResult 完整内容确认 Data 是否存在及结构。
- 核对 config.spaceName 与火山 VOD 控制台中的空间名一致且已开通。
- 确认上传 Functions 配置(GetMeta/AddOptionInfo)未被裁剪。
- 检查 @volcengine/openapi SDK 版本是否与响应结构匹配,必要时升级或降级。
Example fix
// before
const vid = await uploadService.downloadUrlAndUploadAsStream(url)
// after
let vid: string
try {
vid = await uploadService.downloadUrlAndUploadAsStream(url)
} catch (e) {
if ((e as any)?.code === ResponseCode.VideoUploadVidNotFound) {
logger.error({ spaceName: process.env.VOLCSPACE_NAME }, 'Upload ok but no Vid; check VOD space config')
}
throw e
} Defensive patterns
Strategy: validation
Validate before calling
if (!process.env.VOLCSPACE_NAME) throw new Error('VOLCSPACE_NAME must be set')
// verify space exists once at startup via ListSpace or console check Type guard
function hasVid(r: unknown): r is { Data: { Vid: string } } {
return r != null && typeof r === 'object'
&& typeof (r as any).Data?.Vid === 'string' && (r as any).Data.Vid.length > 0
} Try / catch
try {
vid = await downloadUrlAndUploadAsStream(url)
} catch (e) {
if ((e as any)?.code === ResponseCode.VideoUploadVidNotFound) {
logger.error({ spaceName: config.spaceName }, 'No Vid returned; verify VOD space and SDK response shape')
}
throw e
} Prevention
- 启动时校验 SpaceName 与火山 VOD 控制台一致
- 保持 uploadMaterial 的 Functions(GetMeta/AddOptionInfo)完整
- 升级火山 SDK 后用单元用例断言 Data.Vid 存在
- 保留 uploadResult 完整响应日志以便排查
When it happens
Trigger: UploadMaterial 响应无 Error 但 Data.Vid 缺失:SpaceName 配置错误/不存在、GetMeta Function 未返回媒体信息、响应结构变化、上传的实际上下文被 VOD 接受但未生成媒体记录。
Common situations: VOLCSPACE_NAME 环境变量指向错误或未初始化的空间;火山 VOD 服务未在该空间开通媒体上传;SDK 升级后 Result.Data 结构改变;上传了非视频内容导致无 Vid。
Related errors
- InvalidModel
- VideoUploadFailed
- Relay uploadSign returned no uploadUrl: ${JSON.stringify(sig
- InvalidModel
- InvalidModel
AI-assisted analysis of yikart/AiToEarn@d3aa8bea5b (2026-08-31).
Data as JSON: /api/errors/4f407dc9dbd5b17b.
Report an issue: GitHub.