BerriAI/litellm · error · NotImplementedError
Export format '{self.export_format}' not supported. Use 'par
Error message
Export format '{self.export_format}' not supported. Use 'parquet' or 'csv'. What it means
FocusExportEngine._init_serializer raises NotImplementedError when export_format is neither 'csv' nor 'parquet'. The engine maps the format string to a serializer class (FocusCsvSerializer / FocusParquetSerializer); anything else has no implementation.
Source
Thrown at litellm/integrations/focus/export_engine.py:45
) -> None:
self.provider = provider
self.export_format = export_format
self.prefix = prefix
self._destination = FocusDestinationFactory.create(
provider=self.provider,
prefix=self.prefix,
config=destination_config,
)
self._serializer = self._init_serializer()
self._transformer = FocusTransformer()
self._database = FocusLiteLLMDatabase()
def _init_serializer(self) -> FocusSerializer:
if self.export_format == "csv":
return FocusCsvSerializer()
if self.export_format == "parquet":
return FocusParquetSerializer()
raise NotImplementedError(f"Export format '{self.export_format}' not supported. Use 'parquet' or 'csv'.")
async def dry_run_export_usage_data(self, limit: int | None) -> dict[str, Any]:
data: Final = await self._database.get_usage_data(limit=limit)
normalized: Final = self._transformer.transform(data)
usage_sample: Final = data.head(min(50, len(data))).to_dicts()
normalized_sample: Final = normalized.head(min(50, len(normalized))).to_dicts()
summary: Final = {
"total_records": len(normalized),
"total_spend": self._sum_column(data, "spend"),
"total_tokens": self._sum_column(data, "total_tokens"),
"unique_teams": self._count_unique(data, "team_id"),
"unique_models": self._count_unique(data, "model"),
}
return {
"usage_data": usage_sample,View on GitHub (pinned to 6c2dcb801b)
Solutions
- Set export_format to exactly 'parquet' or 'csv' (lowercase).
- Validate/normalize the value (strip + lower) in your config layer before constructing the engine.
- If you need another format, subclass FocusSerializer and register it — do not expect built-in support.
Example fix
# before FocusExportEngine(export_format="JSON", ...) # after FocusExportEngine(export_format="parquet", ...)
Defensive patterns
Strategy: validation
Validate before calling
fmt = (export_format or "").strip().lower()
if fmt not in {"parquet", "csv"}:
raise ValueError(f"export_format must be 'parquet' or 'csv', got {export_format!r}")
engine = FocusExportEngine(export_format=fmt, ...) Type guard
from typing import Literal
FocusFormat = Literal["parquet", "csv"]
def is_focus_format(v: str) -> bool:
return v in {"parquet", "csv"} Prevention
- Type the setting as Literal['parquet','csv'] in your config model so bad values fail at load.
- Normalize case/whitespace on the format before constructing the engine.
- Document the supported formats in the config template next to the key.
When it happens
Trigger: Initializing FocusExportEngine with export_format='json', 'JSON', 'Parquet' (case-sensitive), or None via constructor or settings/env-driven config.
Common situations: Case mismatch ('CSV' vs 'csv'); copy-pasting a format from a different tool's docs; leaving an empty string default from templated config.
Related errors
- bucket_name must be provided for S3 destination
- Unsupported frequency: {self.frequency}
- Event hook {hook} is not in the supported event hooks {suppo
- Event hook {event_hook} is not in the supported event hooks
- Invalid environment: {environment}. Please use one of the fo
AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15).
Data as JSON: /api/errors/c7e9af4be5d2eab0.
Report an issue: GitHub.