fishaudio/fish-speech · error · FileExistsError

Reference ID '{id}' already exists

Error message

Reference ID '{id}' already exists

What it means

add_reference stores each voice reference under references/<id>/. If that directory already exists, the ID is taken and a FileExistsError is raised before any file is written, preventing silent overwrites of existing references.

Source

Thrown at fish_speech/inference_engine/reference_loader.py:209

        """
        Add a new reference voice by creating a new directory and copying files.

        Args:
            id: Reference ID (directory name)
            wav_file_path: Path to the audio file to copy
            reference_text: Text content for the .lab file

        Raises:
            FileExistsError: If the reference ID already exists
            FileNotFoundError: If the audio file doesn't exist
            OSError: If file operations fail
        """
        self._validate_id(id)

        # Check if reference already exists
        ref_dir = Path("references") / id
        if ref_dir.exists():
            raise FileExistsError(f"Reference ID '{id}' already exists")

        # Check if audio file exists
        audio_path = Path(wav_file_path)
        if not audio_path.exists():
            raise FileNotFoundError(f"Audio file not found: {wav_file_path}")

        # Validate audio file extension
        if audio_path.suffix.lower() not in AUDIO_EXTENSIONS:
            raise ValueError(
                f"Unsupported audio format: {audio_path.suffix}. Supported formats: {', '.join(AUDIO_EXTENSIONS)}"
            )

        try:
            # Create reference directory
            ref_dir.mkdir(parents=True, exist_ok=False)

            # Determine the target audio filename with original extension
            target_audio_path = ref_dir / f"sample{audio_path.suffix}"

View on GitHub (pinned to befe400174)

Solutions

  1. Use delete_reference(id) first, then add_reference again
  2. Choose a unique ID (append a suffix/version, e.g. "speaker_v2")
  3. Wrap add_reference in try/except FileExistsError for idempotent ingestion scripts

Example fix

# before
loader.add_reference("my_voice", "a.wav")  # FileExistsError on second run

# after
try:
    loader.add_reference("my_voice", "a.wav")
except FileExistsError:
    loader.delete_reference("my_voice")
    loader.add_reference("my_voice", "a.wav")
Defensive patterns

Strategy: try-catch

Validate before calling

from pathlib import Path
if (Path("references") / ref_id).exists():
    print(f"reference '{ref_id}' already registered; skipping or replacing")

Try / catch

try:
    loader.add_reference(ref_id, wav)
except FileExistsError:
    loader.delete_reference(ref_id)
    loader.add_reference(ref_id, wav)

Prevention

When it happens

Trigger: Calling add_reference(id=...) twice with the same ID (even if the wav differs), or re-running a script that registers references after a previous partial/complete run.

Common situations: Re-running ingestion scripts without cleanup, retrying after a failure that had already created the directory (mkdir with exist_ok=False happens later, but this check fires first).

Related errors


AI-assisted analysis of fishaudio/fish-speech@befe400174 (2026-08-27). Data as JSON: /api/errors/2fbcbdd475caf018. Report an issue: GitHub.