{"record":{"id":"382aec666be41185","repo":"unclecode/crawl4ai","slug":"the-markdown-v2-attribute-is-deprecated-and-has-382aec","errorCode":null,"errorMessage":"The 'markdown_v2' attribute is deprecated and has been removed. Please use 'markdown' instead, which now returns a MarkdownGenerationResult, with\n            following properties:\n            - raw_markdown: The raw markdown string\n            - markdown_with_citations: The markdown string with citations\n            - references_markdown: The markdown string with references\n            - fit_markdown: The markdown string with fit text\n            ","messagePattern":"The 'markdown_v2' attribute is deprecated and has been removed\\. Please use 'markdown' instead, which now returns a MarkdownGenerationResult, with\n            following properties:\n            - raw_markdown: The raw markdown string\n            - markdown_with_citations: The markdown string with citations\n            - references_markdown: The markdown string with references\n            - fit_markdown: The markdown string with fit text\n            ","errorType":"exception","errorClass":"AttributeError","httpStatus":null,"severity":"warning","filePath":"crawl4ai/models.py:216","lineNumber":5419,"sourceCode":"            return None\n        return StringCompatibleMarkdown(self._markdown)\n    \n    @markdown.setter\n    def markdown(self, value):\n        \"\"\"\n        Setter for the markdown property.\n        \"\"\"\n        self._markdown = value\n    \n    @property\n    def markdown_v2(self):\n        \"\"\"\n        Deprecated property that raises an AttributeError when accessed.\n\n        This property exists to inform users that 'markdown_v2' has been\n        deprecated and they should use 'markdown' instead.\n        \"\"\"\n        raise AttributeError(\n            \"The 'markdown_v2' attribute is deprecated and has been removed. \"\n            \"\"\"Please use 'markdown' instead, which now returns a MarkdownGenerationResult, with\n            following properties:\n            - raw_markdown: The raw markdown string\n            - markdown_with_citations: The markdown string with citations\n            - references_markdown: The markdown string with references\n            - fit_markdown: The markdown string with fit text\n            \"\"\"\n        )\n    \n    @property\n    def fit_markdown(self):\n        \"\"\"\n        Deprecated property that raises an AttributeError when accessed.\n        \"\"\"\n        raise AttributeError(\n            \"The 'fit_markdown' attribute is deprecated and has been removed. \"\n            \"Please use 'markdown.fit_markdown' instead.\"","sourceCodeStart":5401,"sourceCodeEnd":5437,"githubUrl":"https://github.com/unclecode/crawl4ai/blob/7e801521428ee12509994d39151006f64055ebe3/deploy/docker/c4ai-code-context.md#L5401-L5437","documentation":"CrawlResult previously exposed markdown_v2, which returned a structured MarkdownGenerationResult; that API was renamed so that the plain markdown property now returns MarkdownGenerationResult. Accessing markdown_v2 raises an intentional AttributeError explaining the new shape (raw_markdown, markdown_with_citations, references_markdown, fit_markdown).","triggerScenarios":"Accessing result.markdown_v2 on a CrawlResult after upgrading crawl4ai; code written against the 0.5.x-era API where markdown_v2 coexisted with the legacy string markdown.","commonSituations":"Upgrading crawl4ai across the markdown/markdown_v2 unification; tutorials or cookbook code referencing markdown_v2; generic code doing getattr(result, 'markdown_v2', ...) which still triggers the property (the property itself raises, so getattr without default does not protect you).","solutions":["Replace result.markdown_v2 with result.markdown — it now returns the same MarkdownGenerationResult","Use the specific field you need: result.markdown.raw_markdown, result.markdown.fit_markdown, result.markdown.markdown_with_citations","If you only want the plain string, str(result.markdown) or result.markdown.raw_markdown"],"exampleFix":"// before\nmd = result.markdown_v2.raw_markdown\n// after\nmd = result.markdown.raw_markdown\n","handlingStrategy":"type-guard","validationCode":"def get_markdown_v2_style(result):\n    # modern API: markdown is MarkdownGenerationResult\n    return result.markdown  # use .raw_markdown / .fit_markdown on it","typeGuard":"def has_markdown_result(result) -> bool:\n    md = getattr(result, \"markdown\", None)\n    return md is not None and hasattr(md, \"raw_markdown\") and hasattr(md, \"fit_markdown\")","tryCatchPattern":"try:\n    md = result.markdown_v2\nexcept AttributeError:\n    md = result.markdown  # new MarkdownGenerationResult\n","preventionTips":["Grep your codebase for markdown_v2 before every crawl4ai upgrade","Pin the crawl4ai version in requirements until migration is done","Use hasattr(result.markdown, 'raw_markdown') to branch on old vs new shape during migration"],"tags":["crawl4ai","deprecation","markdown","crawl-result"],"backgroundTag":null,"analyzedSha":"7e801521428ee12509994d39151006f64055ebe3","analyzedAt":"2026-08-14T20:46:20.673Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}