{"record":{"id":"2ef9ff52360ab645","repo":"yikart/AiToEarn","slug":"aicallfailed-2ef9ff","errorCode":"AiCallFailed","errorMessage":"Relay task id is missing","messagePattern":"Relay task id is missing","errorType":"error_code","errorClass":"AppException","httpStatus":null,"severity":"error","filePath":"project/aitoearn-backend/apps/aitoearn-ai/src/core/ai/video/relay/relay-video.service.ts","lineNumber":56,"sourceCode":"    }\n    const startedAt = new Date()\n\n    const payload = { ...request } as RelayVideoGenerationRequest & { userId?: string, userType?: UserType, groupId?: string }\n    delete payload.userId\n    delete payload.userType\n    delete payload.groupId\n\n    const relayPayload = await this.resolveRelayJson(payload)\n\n    const result = await this.aiAvailability.executeAsync<RelayVideoSubmitResponse>(\n      { provider: 'relay', operation: 'videoGeneration', model: request.model },\n      () => this.relayLibService.createVideo(relayPayload),\n      response => response.id || '',\n    )\n\n    const remoteTaskId = result.id\n    if (!remoteTaskId) {\n      throw new AppException(ResponseCode.AiCallFailed, { error: 'Relay task id is missing' })\n    }\n\n    const logRequest: RelayVideoAiLog['request'] = {\n      ...payload,\n      remoteTaskId,\n    }\n    if (request.groupId) {\n      logRequest.groupId = request.groupId\n    }\n\n    const aiLog = await this.aiLogRepo.create({\n      userId: request.userId,\n      userType: request.userType,\n      taskId: remoteTaskId,\n      model: request.model,\n      channel: AiLogChannel.Relay,\n      startedAt,\n      type: AiLogType.Video,","sourceCodeStart":38,"sourceCodeEnd":74,"githubUrl":"https://github.com/yikart/AiToEarn/blob/d3aa8bea5b146a8675607cf0144d891aad3e9683/project/aitoearn-backend/apps/aitoearn-ai/src/core/ai/video/relay/relay-video.service.ts#L38-L74","documentation":"AiCallFailed with detail 'Relay task id is missing' is thrown by RelayVideoService.createFromRequest when the upstream Relay createVideo call succeeded (or returned) without an id. The service extracts result.id via a response interceptor and treats an empty id as a failed Relay call since no task can be tracked without it.","triggerScenarios":"The relayLibService.createVideo(relayPayload) response resolved but its id field was empty/undefined, so `if (!remoteTaskId)` fired.","commonSituations":"Relay upstream changed its response schema (id renamed or nested); Relay returned a 2xx error envelope without an id; network proxy stripped the body; Relay-side quota/auth failure surfaced as a success-shaped empty response; timeout handling returned a partial object.","solutions":["Inspect the raw Relay createVideo response to confirm the id field name/shape matches what the interceptor reads","Verify Relay credentials (RELAY_API_KEY / RELAY_SERVER_URL) and that the Relay service is healthy","Add validation on the Relay library side to surface non-2xx or malformed envelopes as distinct errors","Retry the creation; if persistent, report the payload to Relay support and check for API version changes"],"exampleFix":"// before (library interceptor)\nresponse => response.id || ''\n// after\nresponse => {\n  if (!response?.id) throw new Error(`Relay createVideo returned no id: ${JSON.stringify(response)}`)\n  return response.id\n}","handlingStrategy":"retry","validationCode":"// no pre-call check possible; validate after the call\nconst id = response?.id\nif (typeof id !== 'string' || id.length === 0) throw new Error('Relay returned no task id')","typeGuard":"function hasTaskId(r: unknown): r is { id: string } {\n  return typeof r === 'object' && r !== null && typeof (r as any).id === 'string' && (r as any).id.length > 0\n}","tryCatchPattern":"try {\n  const { id } = await relayVideoService.createFromRequest(req)\n} catch (e) {\n  if (e instanceof AppException && e.code === ResponseCode.AiCallFailed) {\n    // inspect e.meta.error ('Relay task id is missing'), check Relay health/credentials, retry once\n  } else throw e\n}","preventionTips":["Monitor Relay upstream for response schema changes","Verify RELAY_API_KEY/RELAY_SERVER_URL health before large batches","Log full raw Relay responses to diagnose empty ids","Implement one safe retry for id-less responses"],"tags":["relay","video","upstream","missing-task-id"],"backgroundTag":"relay-task-id-missing","analyzedSha":"d3aa8bea5b146a8675607cf0144d891aad3e9683","analyzedAt":"2026-08-31T14:19:24.185Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}