{"record":{"id":"c608d5f7b34f24a5","repo":"n8n-io/n8n","slug":"failed-to-retrieve-download-url-for-file-fileid","errorCode":null,"errorMessage":"Failed to retrieve download URL for file ${fileId}","messagePattern":"Failed to retrieve download URL for file (.+?)","errorType":"exception","errorClass":"NodeOperationError","httpStatus":null,"severity":"error","filePath":"packages/@n8n/nodes-langchain/nodes/vendors/MiniMax/transport/index.ts","lineNumber":98,"sourceCode":"\t}\n\n\tthrow new NodeOperationError(\n\t\tthis.getNode(),\n\t\t`Video task ${taskId} did not complete within the maximum polling time. You can query the task manually using the task ID.`,\n\t);\n}\n\nexport async function getVideoDownloadUrl(\n\tthis: IExecuteFunctions,\n\tfileId: string,\n): Promise<string> {\n\tconst response = await apiRequest.call(this, 'GET', '/files/retrieve', {\n\t\tqs: { file_id: fileId },\n\t});\n\n\tconst downloadUrl = response?.file?.download_url as string;\n\tif (!downloadUrl) {\n\t\tthrow new NodeOperationError(\n\t\t\tthis.getNode(),\n\t\t\t`Failed to retrieve download URL for file ${fileId}`,\n\t\t);\n\t}\n\n\treturn downloadUrl;\n}\n","sourceCodeStart":80,"sourceCodeEnd":106,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/nodes-langchain/nodes/vendors/MiniMax/transport/index.ts#L80-L106","documentation":"Thrown by getVideoDownloadUrl when GET /files/retrieve returns a response whose response.file.download_url is missing. After polling confirms Success and yields a file_id, this second call fetches the signed download URL; absence of download_url means the node cannot retrieve the rendered video bytes.","triggerScenarios":"File not yet materialized in MiniMax's storage when /files/retrieve was called (race after Success); file TTL expired between job completion and retrieval call; permission/quota issue preventing download URL minting; API revision moving download_url to a different field; proxy stripping the field.","commonSituations":"Tight race between Success and file availability; long delay between poll completion and retrieval (file GC'd); account download permission revoked; non-official base URL filtering the response.","solutions":["Retry GET /files/retrieve?file_id=<id> after a short delay to let the file materialize.","Log the full response to confirm download_url is absent vs. relocated.","If the file_id is old, resubmit the video generation — the file may have been garbage-collected.","Verify the credentials base URL is the official MiniMax endpoint."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// No caller-side input prevents an upstream missing-download_url response.\n// Validate only that the fileId you pass is a non-empty string.\nfunction validateFileId(fileId: unknown): string | null {\n  if (typeof fileId !== 'string' || fileId.length === 0) return 'fileId must be a non-empty string';\n  return null;\n}","typeGuard":"function hasDownloadUrl(r: unknown): r is { file: { download_url: string } } {\n  const url = (r as { file?: { download_url?: unknown } })?.file?.download_url;\n  return typeof url === 'string' && url.length > 0;\n}","tryCatchPattern":"async function getDownloadUrlWithRetry(apiRequest: any, fileId: string, maxAttempts = 3): Promise<string> {\n  for (let attempt = 0; attempt < maxAttempts; attempt++) {\n    const response = await apiRequest.call(this, 'GET', '/files/retrieve', { qs: { file_id: fileId } });\n    const url = response?.file?.download_url as string | undefined;\n    if (url) return url;\n    await sleep(2000 * (attempt + 1)); // let the file materialize\n  }\n  throw new NodeOperationError(this.getNode(), `Failed to retrieve download URL for file ${fileId}`);\n}","preventionTips":["Retry /files/retrieve a few times after Success — the file may still be materializing.","Retrieve the download URL promptly after polling to avoid file TTL/garbage-collection.","Log the full response to distinguish a real API field rename from a race.","Use the official MiniMax base URL to avoid proxies stripping the download_url field."],"tags":["minimax","video-generation","download","response-shape","race"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}