{"record":{"id":"2ce1d1439e63934e","repo":"Mintplex-Labs/anything-llm","slug":"audio-file-duration-exceeds-maximum-limit-of-4-hou","errorCode":null,"errorMessage":"Audio file duration exceeds maximum limit of 4 hours.","messagePattern":"Audio file duration exceeds maximum limit of 4 hours\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"collector/utils/WhisperProviders/localWhisper.js","lineNumber":48,"sourceCode":"  }\n\n  #validateAudioFile(wavFile) {\n    const sampleRate = wavFile.fmt.sampleRate;\n    const duration = wavFile.data.samples / sampleRate;\n\n    // Most speech recognition systems expect minimum 8kHz\n    // But we'll set it lower to be safe\n    if (sampleRate < 4000) {\n      // 4kHz minimum\n      throw new Error(\n        \"Audio file sample rate is too low for accurate transcription. Minimum required is 4kHz.\"\n      );\n    }\n\n    // Typical audio file duration limits\n    const MAX_DURATION_SECONDS = 4 * 60 * 60; // 4 hours\n    if (duration > MAX_DURATION_SECONDS) {\n      throw new Error(\"Audio file duration exceeds maximum limit of 4 hours.\");\n    }\n\n    // Check final sample count after upsampling to prevent memory issues\n    const targetSampleRate = 16000;\n    const upsampledSamples = duration * targetSampleRate;\n    const MAX_SAMPLES = 230_400_000; // ~4 hours at 16kHz\n\n    if (upsampledSamples > MAX_SAMPLES) {\n      throw new Error(\"Audio file exceeds maximum allowed length.\");\n    }\n\n    return true;\n  }\n\n  async #convertToWavAudioData(sourcePath) {\n    try {\n      let buffer;\n      const wavefile = require(\"wavefile\");","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/Mintplex-Labs/anything-llm/blob/526360e320da9d1b36074be5ed64fe76e5bbfbbd/collector/utils/WhisperProviders/localWhisper.js#L30-L66","documentation":"Rejects WAVs longer than 14400 seconds (4 hours), computed as data.samples / sampleRate. Guards against runaway memory and CPU use during Whisper transcription.","triggerScenarios":"A genuinely long recording (>4 h) reaches validation, or a mis-parsed header inflates data.samples relative to sampleRate.","commonSituations":"Multi-hour podcasts/lectures; concatenated audio; a corrupt header reporting a huge sample count.","solutions":["Split the source into <4 h segments before transcription.","Trim to the relevant portion.","Sanity-check the header-derived duration against file size."],"exampleFix":"// before\nconst MAX_DURATION_SECONDS = 4 * 60 * 60;\nif (duration > MAX_DURATION_SECONDS) throw new Error(\"...4 hours.\");\n\n// after — configurable limit + actual duration reported\nconst MAX_DURATION_SECONDS = opts.maxDuration ?? (4 * 60 * 60);\nif (duration > MAX_DURATION_SECONDS)\n  throw new Error(`Duration ${duration}s exceeds ${MAX_DURATION_SECONDS}s.`);","handlingStrategy":"validation","validationCode":"function durationSeconds(wav) {\n  return wav.data.samples / wav.fmt.sampleRate;\n}\n// if (durationSeconds(wav) > 14400) split the file before transcription;","typeGuard":null,"tryCatchPattern":"try { this.#validateAudioFile(wavFile); }\ncatch (e) {\n  if (e.message.includes(\"duration exceeds\")) { /* chunk and retry */ }\n  throw e;\n}","preventionTips":["Segment long recordings before ingestion.","Expose duration limits in user-facing upload guidance.","Sanity-check header-derived duration against file size."],"tags":["audio","whisper","validation","duration","limits"],"backgroundTag":null,"analyzedSha":"526360e320da9d1b36074be5ed64fe76e5bbfbbd","analyzedAt":"2026-08-13T01:45:47.170Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}