{"record":{"id":"342ee266fdeb3830","repo":"Mintplex-Labs/anything-llm","slug":"invalid-audio-upload-err-message","errorCode":null,"errorMessage":"Invalid audio upload. ${err.message}","messagePattern":"Invalid audio upload\\. (.+?)","errorType":"http","errorClass":null,"httpStatus":500,"severity":"error","filePath":"server/utils/files/multer.js","lineNumber":189,"sourceCode":"}\n\n/**\n * Handle in-memory audio upload for STT transcription. Audio buffers are\n * passed straight to the STT provider so we never persist them to disk.\n */\nfunction handleAudioUpload(request, response, next) {\n  const upload = multer({\n    storage: multer.memoryStorage(),\n    limits: { fileSize: 25 * 1024 * 1024 }, // 25MB matches OpenAI Whisper limit\n    fileFilter: (_req, file, cb) => {\n      if (!file.mimetype?.startsWith(\"audio/\"))\n        return cb(new Error(\"Only audio uploads are allowed.\"));\n      cb(null, true);\n    },\n  }).single(\"audio\");\n  upload(request, response, function (err) {\n    if (err) {\n      return response.status(500).json({\n        success: false,\n        error: `Invalid audio upload. ${err.message}`,\n      });\n    }\n    next();\n  });\n}\n\n/**\n * Handle in-memory image upload for image generation/editing. Buffers are\n * passed directly to the image generation provider, never persisted to disk.\n */\nfunction handleImageGenUpload(request, response, next) {\n  const upload = multer({\n    storage: multer.memoryStorage(),\n    limits: { fileSize: 25 * 1024 * 1024 },\n    fileFilter: (_req, file, cb) => {\n      if (!file.mimetype?.startsWith(\"image/\"))","sourceCodeStart":171,"sourceCodeEnd":207,"githubUrl":"https://github.com/Mintplex-Labs/anything-llm/blob/3aec848f2885144aa8f1e53b9731a04310d5d558/server/utils/files/multer.js#L171-L207","documentation":"Error from the in-memory audio upload middleware used for transcription (Whisper). It configures multer with memoryStorage, a per-file 25MB limit matching the OpenAI Whisper cap, a fileFilter that rejects any mimetype not starting with 'audio/', and .single('audio'). Any violation returns HTTP 500 with 'Invalid audio upload. <err.message>' — typical err.message values are 'File too large' (LIMIT_FILE_SIZE), 'Only audio uploads are allowed.' (fileFilter), or 'Unexpected field' (wrong part name).","triggerScenarios":"POST multipart to the transcribe/voice endpoint with the part named other than 'audio'; audio file over 25MB; a file whose declared mimetype is video/mp4 or application/octet-stream even though it carries an audio track (the filter checks mimetype, not content).","commonSituations":"Uploading long recordings that exceed 25MB; phones producing .mp4/.mov containers whose mimetype is video/*; clients naming the part 'file' or 'audioFile'; files sent with a generic application/octet-stream mimetype by a proxy or SDK.","solutions":["Send the file as the part named 'audio' with a mimetype starting with 'audio/' (e.g. audio/mpeg, audio/wav, audio/webm)","Compress, trim, or convert the audio so it is under 25MB — this is a hard Whisper-aligned cap","Re-encode video containers (mp4/mov) to an audio-only format so the mimetype is audio/*","Send exactly one file part in a well-formed multipart body"],"exampleFix":"// before\nfd.append('file', videoFile); // part 'file', type video/mp4 -> rejected twice\n\n// after\n// extract audio track first, then:\nfd.append('audio', audioBlob /* Blob type 'audio/mpeg' */);","handlingStrategy":"validation","validationCode":"const MAX = 25 * 1024 * 1024;\nif (!audioFile.type.startsWith('audio/')) throw new Error('Convert to an audio/* container first');\nif (audioFile.size > MAX) throw new Error('Audio exceeds 25MB Whisper cap');\nconst fd = new FormData();\nfd.append('audio', audioFile);","typeGuard":"const isUploadableAudio = (f) =>\n  f instanceof File && f.type.startsWith('audio/') && f.size <= 25 * 1024 * 1024;","tryCatchPattern":"if (!res.ok) {\n  const { error } = await res.json();\n  if (/File too large/.test(error)) recompressOrTrim();\n  if (/Only audio uploads/.test(error)) reencodeToAudioContainer();\n}","preventionTips":["Strip video containers to audio-only before upload","Show the 25MB limit in the recorder UI before the user records an hour","Set explicit Blob type when uploading recorded chunks (they default to empty mimetype)"],"tags":["multer","audio","whisper","transcription","file-size-limit"],"backgroundTag":"multipart-upload-rejected","analyzedSha":"3aec848f2885144aa8f1e53b9731a04310d5d558","analyzedAt":"2026-08-18T10:02:21.017Z","contentChangedAt":"2026-08-18T10:02:21.017Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}