{"record":{"id":"bdf13ac0e5d80781","repo":"mudler/LocalAI","slug":"audio-contains-no-samples","errorCode":null,"errorMessage":"audio contains no samples","messagePattern":"audio contains no samples","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"backend/python/longcat-video/backend.py","lineNumber":653,"sourceCode":"        )\n        audio_guidance = (\n            1.0\n            if use_distill\n            else require_float(\n                params.get(\"audio_guidance_scale\", 4.0),\n                \"audio_guidance_scale\",\n                minimum=0.0,\n                maximum=20.0,\n            )\n        )\n        seed = request.seed if request.seed > 0 else 42\n        generator = self.torch.Generator(device=self.device_index).manual_seed(seed)\n        negative_prompt = request.negative_prompt or DEFAULT_NEGATIVE_PROMPT\n        resolution = self._resolution(params)\n\n        speech, sample_rate = self.librosa.load(request.audio, sr=16000, mono=True)\n        if speech.size == 0:\n            raise ValueError(\"audio contains no samples\")\n        audio_duration = len(speech) / sample_rate\n        segments = self._avatar_segments(request, params, audio_duration)\n\n        segment_frames = 93\n        conditioning_frames = 13\n        avatar_fps = 25\n        generated_duration = (\n            segment_frames + (segments - 1) * (segment_frames - conditioning_frames)\n        ) / avatar_fps\n        pad_samples = max(\n            0, math.ceil((generated_duration - audio_duration) * sample_rate)\n        )\n        if pad_samples:\n            speech = self.np.pad(speech, (0, pad_samples))\n\n        full_audio_embedding = self.pipeline.get_audio_embedding(\n            speech,\n            fps=avatar_fps,","sourceCodeStart":635,"sourceCodeEnd":671,"githubUrl":"https://github.com/mudler/LocalAI/blob/44413a9d06bf5bc52ce088ba8ca74e5a2e8bee26/backend/python/longcat-video/backend.py#L635-L671","documentation":"ValueError after librosa.load(request.audio, sr=16000, mono=True) returns an empty array (speech.size == 0). The file existed but decoded to zero samples — typically a zero-byte or header-only audio file, or one ffmpeg/soundfile silently decodes to nothing. Duration math (len(speech)/sample_rate) would be nonsensical, so generation aborts.","triggerScenarios":"Uploading a 0-byte or truncated wav/mp3; a file with valid container headers but no audio frames; a codec mismatch where the decoder finds no audio stream.","commonSituations":"Upload pipeline truncated the file; TTS step produced an empty output that was passed straight to video generation; wrong file extension (e.g. .wav containing text).","solutions":["Inspect the file on the backend host: ffprobe /path/audio to confirm it has an audio stream with duration > 0","Re-export or regenerate the audio, then re-stage and retry","Add a client-side sanity check that the file size and decoded duration are non-zero before sending"],"exampleFix":"# before\n# staged file was truncated during upload\n\n# after\nimport subprocess\n subprocess.run([\"ffmpeg\",\"-y\",\"-i\",\"raw.webm\",\"/data/staged/voice.wav\"], check=True)  # full re-encode, verify with ffprobe","handlingStrategy":"validation","validationCode":"import os, subprocess, json\n\ndef audio_has_samples(path: str, min_seconds: float = 0.1) -> bool:\n    if not os.path.isfile(path) or os.path.getsize(path) == 0:\n        return False\n    out = subprocess.run(\n        [\"ffprobe\", \"-v\", \"error\", \"-show_entries\", \"format=duration\",\n         \"-of\", \"json\", path], capture_output=True, text=True)\n    if out.returncode != 0:\n        return False\n    try:\n        return float(json.loads(out.stdout)[\"format\"][\"duration\"]) >= min_seconds\n    except (KeyError, ValueError):\n        return False","typeGuard":null,"tryCatchPattern":"try:\n    stub.GenerateVideo(req)\nexcept grpc.RpcError as e:\n    if \"no samples\" in (e.details() or \"\"):\n        raise UserError(\"Audio file is empty or unreadable; re-export it\") from e\n    raise","preventionTips":["Probe uploaded audio (duration > 0) before staging","Standardize on re-encoded 16 kHz mono wav produced by your own ffmpeg step"],"tags":["python","longcat-video","audio","file-handling","validation"],"backgroundTag":null,"analyzedSha":"44413a9d06bf5bc52ce088ba8ca74e5a2e8bee26","analyzedAt":"2026-08-15T10:13:50.291Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}