{"record":{"id":"f65085a29bce8963","repo":"makeplane/plane","slug":"unsupported-format-format-type-available-lis","errorCode":null,"errorMessage":"Unsupported format: {format_type}. Available: {list(self.FORMATTERS.keys())}","messagePattern":"Unsupported format: (.+?)\\. Available: (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"apps/api/plane/utils/exporters/exporter.py","lineNumber":31,"sourceCode":"    \"\"\"Generic exporter class that handles data exports using different formatters.\"\"\"\n\n    # Available formatters\n    FORMATTERS = {\n        \"csv\": CSVFormatter,\n        \"json\": JSONFormatter,\n        \"xlsx\": XLSXFormatter,\n    }\n\n    def __init__(self, format_type: str, schema_class: Type, options: Dict[str, Any] = None):\n        \"\"\"Initialize exporter with specified format type and schema.\n\n        Args:\n            format_type: The export format (csv, json, xlsx)\n            schema_class: The schema class to use for field definitions\n            options: Optional formatting options\n        \"\"\"\n        if format_type not in self.FORMATTERS:\n            raise ValueError(f\"Unsupported format: {format_type}. Available: {list(self.FORMATTERS.keys())}\")\n\n        self.format_type = format_type\n        self.schema_class = schema_class\n        self.formatter = self.FORMATTERS[format_type]()\n        self.options = options or {}\n\n    def export(\n        self,\n        filename: str,\n        data: Union[QuerySet, List[dict]],\n        fields: List[str] = None,\n    ) -> tuple[str, str | bytes]:\n        \"\"\"Export data using the configured formatter and return (filename, content).\n\n        Args:\n            filename: The filename for the export (without extension)\n            data: Either a Django QuerySet or a list of already-serialized dicts\n            fields: Optional list of field names to include in export","sourceCodeStart":13,"sourceCodeEnd":49,"githubUrl":"https://github.com/makeplane/plane/blob/1c8a60f858d8472aa56e29994ec1c7926da2c6ce/apps/api/plane/utils/exporters/exporter.py#L13-L49","documentation":"ValueError raised in `Exporter.__init__` (exporter.py:31) when `format_type` is not a key of the `FORMATTERS` class dict, which contains exactly `csv`, `json`, and `xlsx` (case-sensitive, lowercase). Construction fails before any export runs. The error message lists the available keys to aid diagnosis.","triggerScenarios":"Constructing `Exporter(format_type=..., schema_class=...)` with a format not in {csv, json, xlsx}: e.g. 'XML', 'xls', 'CSV' (uppercase), 'pdf', or a user-supplied format string that wasn't validated.","commonSituations":"User-facing export dropdown that passes an unvalidated format query param; case mismatch ('CSV' vs 'csv'); requesting a format the schema/README mentions in examples (like 'xml') but that has no registered formatter; new format added to the UI but not to FORMATTERS.","solutions":["Pass exactly 'csv', 'json', or 'xlsx' (lowercase) as format_type.","Validate/normalize the format from user input before constructing: `fmt = fmt.lower(); assert fmt in Exporter.get_available_formats()`.","To support a new format, register a formatter via `Exporter.register_formatter('xml', XMLFormatter)` before constructing.","If unsure, call `Exporter.get_available_formats()` to list supported keys dynamically rather than hardcoding."],"exampleFix":"# before\nexporter = Exporter(format_type=request.GET.get('format', 'csv'), schema_class=Schema)\n# user sends ?format=XML -> ValueError\n\n# after\nfmt = request.GET.get('format', 'csv').lower()\nif fmt not in Exporter.get_available_formats():\n    return Response({'error': 'Unsupported format'}, status=400)\nexporter = Exporter(format_type=fmt, schema_class=Schema)","handlingStrategy":"validation","validationCode":"from plane.utils.exporters.exporter import Exporter\n\ndef is_supported_format(fmt: str) -> bool:\n    return fmt in Exporter.FORMATTERS  # {'csv','json','xlsx'}\n\n# normalize before constructing:\n# fmt = fmt.strip().lower()","typeGuard":"from plane.utils.exporters.exporter import Exporter\n\ndef is_supported_format(value: str) -> bool:\n    return isinstance(value, str) and value in Exporter.FORMATTERS","tryCatchPattern":"try:\n    exporter = Exporter(format_type=fmt, schema_class=Schema)\nexcept ValueError as e:\n    if 'Unsupported format' in str(e):\n        return bad_request({'available': Exporter.get_available_formats()})","preventionTips":["Normalize format input with strip().lower() and validate against Exporter.get_available_formats().","Do not pass unvalidated user input straight to the Exporter constructor.","Register new formatters via Exporter.register_formatter before use."],"tags":["export","validation","value-error","format"],"backgroundTag":null,"analyzedSha":"1c8a60f858d8472aa56e29994ec1c7926da2c6ce","analyzedAt":"2026-08-12T14:44:31.636Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}