{"record":{"id":"4690a8b2426f31ca","repo":"unclecode/crawl4ai","slug":"markdown-generator-must-be-an-instance-of-markdown","errorCode":null,"errorMessage":"markdown_generator must be an instance of MarkdownGenerationStrategy, got {type(self.markdown_generator).__name__}.{hint}","messagePattern":"markdown_generator must be an instance of MarkdownGenerationStrategy, got (.+?)\\.(.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"crawl4ai/async_configs.py","lineNumber":1859,"sourceCode":"            raise ValueError(\n                \"extraction_strategy must be an instance of ExtractionStrategy\"\n            )\n        if self.chunking_strategy is not None and not isinstance(\n            self.chunking_strategy, ChunkingStrategy\n        ):\n            raise ValueError(\n                \"chunking_strategy must be an instance of ChunkingStrategy\"\n            )\n        if self.markdown_generator is not None and not isinstance(\n            self.markdown_generator, MarkdownGenerationStrategy\n        ):\n            hint = \"\"\n            if isinstance(self.markdown_generator, dict):\n                hint = (\n                    ' The JSON format must be {\"type\": \"<ClassName>\", \"params\": {...}}.'\n                    ' Note: \"params\" is required — \"options\" or other keys are not recognized.'\n                )\n            raise ValueError(\n                \"markdown_generator must be an instance of MarkdownGenerationStrategy, \"\n                f\"got {type(self.markdown_generator).__name__}.{hint}\"\n            )\n\n        # Set default chunking strategy if None\n        if self.chunking_strategy is None:\n            self.chunking_strategy = RegexChunking()\n\n        # Deep Crawl Parameters\n        self.deep_crawl_strategy = deep_crawl_strategy\n        \n        # Link Extraction Parameters\n        if link_preview_config is None:\n            self.link_preview_config = None\n        elif isinstance(link_preview_config, LinkPreviewConfig):\n            self.link_preview_config = link_preview_config\n        elif isinstance(link_preview_config, dict):\n            # Convert dict to config object for backward compatibility","sourceCodeStart":1841,"sourceCodeEnd":1877,"githubUrl":"https://github.com/unclecode/crawl4ai/blob/7e801521428ee12509994d39151006f64055ebe3/crawl4ai/async_configs.py#L1841-L1877","documentation":"CrawlerRunConfig validation: markdown_generator must be an instance of MarkdownGenerationStrategy (e.g. DefaultMarkdownGenerator) or None. The error message includes the received type name and, when a dict was passed, a hint about the exact JSON shape expected — the dict must use \"type\" and \"params\" keys, and \"params\" is required even when empty.","triggerScenarios":"Passing markdown_generator={\"type\": \"DefaultMarkdownGenerator\", \"options\": {...}} (the rejected 'options' key), a string class name, or another object type.","commonSituations":"Deserializing configs from JSON (API server, dump()/load() roundtrip) with an older or hand-written format that used \"options\" instead of \"params\".","solutions":["For dict input use: {\"type\": \"DefaultMarkdownGenerator\", \"params\": {}} — 'params' is required; 'options' is not recognized","Or pass an instance: markdown_generator=DefaultMarkdownGenerator()","Route raw dicts through CrawlerRunConfig.from_kwargs, which auto-deserializes the {'type','params'} format"],"exampleFix":"// before\nmarkdown_generator={\"type\": \"DefaultMarkdownGenerator\", \"options\": {...}}\n// after\nmarkdown_generator={\"type\": \"DefaultMarkdownGenerator\", \"params\": {\"content_filter\": {...}}}","handlingStrategy":"type-guard","validationCode":"if isinstance(markdown_generator, dict):\n    assert set(markdown_generator) <= {\"type\", \"params\"}, \"use only 'type' and 'params' keys\"\n    markdown_generator.setdefault(\"params\", {})","typeGuard":"from crawl4ai.markdown_generation_strategy import MarkdownGenerationStrategy\n\ndef is_markdown_generator(v) -> bool:\n    return v is None or isinstance(v, MarkdownGenerationStrategy)","tryCatchPattern":null,"preventionTips":["Use {'type': ..., 'params': {...}} exactly; 'params' is required","Migrate old 'options'-key JSON to 'params' once, at load time"],"tags":["validation","markdown","serialization","configuration"],"backgroundTag":null,"analyzedSha":"7e801521428ee12509994d39151006f64055ebe3","analyzedAt":"2026-08-14T20:46:20.673Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}