jamiepine/voicebox · error · ValueError

Error importing profile: {str(e)}

Error message

Error importing profile: {str(e)}

What it means

Catch-all raised by the profile import path for any non-BadZipFile, non-JSONDecodeError, non-ValueError exception that escapes the with-zipfile block (export_import.py:239-242). The original exception's message is appended, so the underlying cause is preserved in the string. This is the wrapper you see when the import failed for a structural reason deeper in create_profile or add_profile_sample.

Source

Thrown at backend/services/export_import.py:242

                        profile.id,
                        tmp_path,
                        reference_text,
                        db,
                    )
                finally:
                    # Clean up temp file
                    Path(tmp_path).unlink(missing_ok=True)
            
            return profile
            
    except zipfile.BadZipFile:
        raise ValueError("Invalid ZIP file")
    except json.JSONDecodeError as e:
        raise ValueError(f"Invalid JSON in archive: {e}")
    except Exception as e:
        if isinstance(e, ValueError):
            raise
        raise ValueError(f"Error importing profile: {str(e)}")


def export_generation_to_zip(generation_id: str, db: Session) -> bytes:
    """
    Export a generation to a ZIP archive.
    
    Args:
        generation_id: Generation ID to export
        db: Database session
        
    Returns:
        ZIP file contents as bytes
        
    Raises:
        ValueError: If generation not found
    """
    # Get generation
    generation = db.query(DBGeneration).filter_by(id=generation_id).first()

View on GitHub (pinned to 51f49dea19)

Solutions

  1. Read the {str(e)} tail to identify the underlying exception type — that drives the fix.
  2. If it is an OSError/PermissionError, check write permissions and free space on the volume backing config.get_profiles_dir().
  3. If it is a sqlalchemy IntegrityError, inspect for duplicate profile names or concurrent imports hitting _get_unique_profile_name.
  4. If it is a KeyError/AttributeError from manifest data, the export format is mismatched — re-export from a matching version.

Example fix

# before: profiles dir not writable
# config.get_profiles_dir() -> /readonly/profiles
# after: point config at a writable dir and retry
export PROFILES_DIR=/var/lib/voicebox/profiles
Defensive patterns

Strategy: try-catch

Validate before calling

null

Type guard

null

Try / catch

try:
    profile = await import_profile_from_bytes(file_bytes, db)
except ValueError as e:
    msg = str(e)
    if msg.startswith('Error importing profile:'):
        # underlying cause is in the tail — log it for ops
        logger.exception('profile import failed: %s', msg)
        raise HTTPException(500, 'Profile import failed; see server logs.')
    raise HTTPException(400, msg)

Prevention

When it happens

Trigger: create_profile raised a DB integrity error (duplicate name not caught by _get_unique_profile_name due to a race); add_profile_sample failed because the disk is full; config.get_profiles_dir() points to an unwritable path; a sample file in samples.json is missing from the archive triggering ValueError already, but any other Exception (OSError, sqlalchemy) lands here.

Common situations: Storage volume full or read-only; DB unique constraint violation from a concurrent import; permissions wrong on the profiles directory; the underlying ValueError messages (e.g. 'Invalid sample filename') are re-raised verbatim by the isinstance(e, ValueError) check, so what you see here is genuinely a non-ValueError.

Related errors


AI-assisted analysis of jamiepine/voicebox@51f49dea19 (2026-08-12). Data as JSON: /api/errors/c3f4408316bf157d. Report an issue: GitHub.