{"record":{"id":"7551dfd28aae2b3e","repo":"danny-avila/LibreChat","slug":"no-download-stream-method-found-for-source-sour","errorCode":null,"errorMessage":"No download stream method found for source: ${source}","messagePattern":"No download stream method found for source: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"api/app/clients/tools/structured/OpenAIImageTools.js","lineNumber":313,"sourceCode":"        if (!imageFile) {\n          continue;\n        }\n        /** @type {NodeStream<File>} */\n        let stream;\n        /** @type {NodeStreamDownloader<File>} */\n        let getDownloadStream;\n        const source = imageFile.source || appFileStrategy;\n        if (!source) {\n          throw new Error('No source found for image file');\n        }\n        if (streamMethods[source]) {\n          getDownloadStream = streamMethods[source];\n        } else {\n          ({ getDownloadStream } = getStrategyFunctions(source));\n          streamMethods[source] = getDownloadStream;\n        }\n        if (!getDownloadStream) {\n          throw new Error(`No download stream method found for source: ${source}`);\n        }\n        stream = await getDownloadStream(req, imageFile.filepath);\n        if (!stream) {\n          throw new Error('Failed to get download stream for image file');\n        }\n        formData.append('image[]', stream, {\n          filename: imageFile.filename,\n          contentType: imageFile.type,\n        });\n      }\n\n      /** @type {import('axios').RawAxiosHeaders} */\n      let headers = {\n        ...formData.getHeaders(),\n      };\n\n      if (process.env.IMAGE_GEN_OAI_AZURE_API_VERSION && process.env.IMAGE_GEN_OAI_BASEURL) {\n        headers['api-key'] = apiKey;","sourceCodeStart":295,"sourceCodeEnd":331,"githubUrl":"https://github.com/danny-avila/LibreChat/blob/5ff282f9006c436e561de1afd39a481bea1ef0d8/api/app/clients/tools/structured/OpenAIImageTools.js#L295-L331","documentation":"Thrown when the resolved `source` is valid enough to call getStrategyFunctions, but the returned strategy object has no `getDownloadStream`. Looking at api/server/services/Files/strategies.js, some strategies legitimately expose getDownloadStream: null (e.g., document_parser, mistral_ocr variants). The tool requires a streamable source to attach the image to the multipart edit request, so a non-streaming strategy is a hard error here.","triggerScenarios":"Editing an image whose source maps to a strategy that does not support streaming — e.g., document_parser, vectordb, or a mistral_ocr source — where getStrategyFunctions returns { getDownloadStream: null } or omits the method.","commonSituations":"User attached a document/OCR-parsed file (source=document_parser) to an image-edit request; a file was mislabeled with a non-image source during upload; a new FileSources value was added without a getDownloadStream implementation; routing a non-image file into the image edit tool.","solutions":["Confirm the attached file's `source` is an image-capable storage (local, s3, firebase, azure_blob, openai) that implements getDownloadStream.","Filter image_ids in the edit tool to files whose source supports streaming before invoking.","If you added a custom FileSources value, implement getDownloadStream in its strategy.","Reject non-image files at the request boundary with a clearer error than the generic one."],"exampleFix":"// before — file.source = 'document_parser' (getDownloadStream: null)\nawait imageEditTool.invoke({ prompt: '...', image_ids: ['file-doc'] });\n\n// after — only pass image-capable files\nconst imageSources = ['local', 's3', 'firebase', 'azure_blob', 'openai'];\nconst editable = files.filter(f => imageSources.includes(f.source));\nawait imageEditTool.invoke({\n  prompt: '...',\n  image_ids: editable.map(f => f.file_id),\n});","handlingStrategy":"type-guard","validationCode":"const STREAMABLE_SOURCES = ['local', 's3', 'firebase', 'azure_blob', 'openai', 'cloudfront'];\nfunction filterStreamableFiles(files) {\n  return files.filter(f => STREAMABLE_SOURCES.includes(f.source));\n}","typeGuard":"function isStreamableSource(source) {\n  return ['local', 's3', 'firebase', 'azure_blob', 'openai', 'cloudfront'].includes(source);\n}","tryCatchPattern":"try {\n  await imageEditTool.invoke(args);\n} catch (e) {\n  if (/No download stream method found for source/.test(e.message)) return 'That file type cannot be streamed for editing.';\n  throw e;\n}","preventionTips":["Filter image_ids to streamable FileSources values before invoking the edit tool.","If you add a new FileSources value, implement getDownloadStream in its strategy.","Do not route document/OCR-parsed files into the image-edit flow."],"tags":["openai-image","file-storage","image-edit","file-strategy","streaming"],"backgroundTag":null,"analyzedSha":"5ff282f9006c436e561de1afd39a481bea1ef0d8","analyzedAt":"2026-08-12T21:38:08.145Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}