mudler/LocalAI · error · RuntimeError

first generated audio path missing or not a file

Error message

first generated audio path missing or not a file

What it means

Raised when result.audios is non-empty but the first entry's 'path' key is missing, empty, or does not point to an existing file on disk. The backend validates the artifact path before shutil.copy2 so it fails fast instead of raising an opaque OSError from copy.

Source

Thrown at backend/python/ace-step/backend.py:285

    try:
        result = generate_music(
            dit_handler=dit_handler,
            llm_handler=llm_handler if (llm_handler and getattr(llm_handler, "llm_initialized", False)) else None,
            params=params,
            config=config,
            save_dir=save_dir,
            progress=None,
        )
        if not result.success:
            raise RuntimeError(result.error or result.status_message or "generate_music failed")

        audios = result.audios or []
        if not audios:
            raise RuntimeError("generate_music returned no audio")

        first_path = audios[0].get("path") or ""
        if not first_path or not os.path.isfile(first_path):
            raise RuntimeError("first generated audio path missing or not a file")

        shutil.copy2(first_path, dst_path)
    finally:
        try:
            shutil.rmtree(save_dir, ignore_errors=True)
        except Exception:
            pass


class BackendServicer(backend_pb2_grpc.BackendServicer):
    def __init__(self):
        self.model_path = None
        self.model_dir = None
        self.checkpoint_dir = None
        self.project_root = None
        self.options = {}
        self.dit_handler = None
        self.llm_handler = None

View on GitHub (pinned to 44413a9d06)

Solutions

  1. Log audios[0] verbatim to see whether 'path' is absent, relative, or absolute-but-missing.
  2. If the path is relative, join it with the save_dir that was passed to generate_music before validating.
  3. Check that nothing (finally-block, cron, container sidecar) removes save_dir before copy2 runs.
  4. Pin/upgrade the ace-step dependency so the audios entry schema matches the expected {'path': ...} contract.

Example fix

// before
first_path = audios[0].get("path") or ""
if not first_path or not os.path.isfile(first_path):
    raise RuntimeError("first generated audio path missing or not a file")

// after (tolerate relative paths from upstream)
first_path = audios[0].get("path") or ""
if first_path and not os.path.isabs(first_path):
    first_path = os.path.join(save_dir, first_path)
if not first_path or not os.path.isfile(first_path):
    raise RuntimeError(f"first generated audio path missing or not a file: {audios[0]!r}")
Defensive patterns

Strategy: validation

Validate before calling

first_path = (result.audios or [{}])[0].get("path") or ""
if first_path and not os.path.isabs(first_path):
    first_path = os.path.join(save_dir, first_path)
assert first_path and os.path.isfile(first_path)

Try / catch

try:
    shutil.copy2(first_path, dst_path)
except (FileNotFoundError, IsADirectoryError) as e:
    raise RuntimeError(f"generated audio vanished before copy: {first_path}") from e

Prevention

When it happens

Trigger: audios[0].get('path') returns None/'' (key missing or empty string), or the path exists as a string but os.path.isfile() is False — e.g. the file was deleted, is a directory, lives on an unmounted share, or is a relative path resolved against a different cwd.

Common situations: Upstream returning relative paths while the backend's working directory differs, an antivirus/cleanup process removing temp files, save_dir being cleaned by a concurrent finally-block, or an audios dict schema change (key renamed from 'path' to something else).

Related errors


AI-assisted analysis of mudler/LocalAI@44413a9d06 (2026-08-15). Data as JSON: /api/errors/9b54418dcf4f0feb. Report an issue: GitHub.