{"record":{"id":"a0b241f75d129175","repo":"unclecode/crawl4ai","slug":"the-fit-html-attribute-is-deprecated-and-has-bee-a0b241","errorCode":null,"errorMessage":"The 'fit_html' attribute is deprecated and has been removed. Please use 'markdown.fit_html' instead.","messagePattern":"The 'fit_html' attribute is deprecated and has been removed\\. Please use 'markdown\\.fit_html' instead\\.","errorType":"exception","errorClass":"AttributeError","httpStatus":null,"severity":"warning","filePath":"crawl4ai/models.py:242","lineNumber":5445,"sourceCode":"            \"\"\"\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.\"\n        )\n    \n    @property\n    def fit_html(self):\n        \"\"\"\n        Deprecated property that raises an AttributeError when accessed.\n        \"\"\"\n        raise AttributeError(\n            \"The 'fit_html' attribute is deprecated and has been removed. \"\n            \"Please use 'markdown.fit_html' instead.\"\n        )\n\n    def model_dump(self, *args, **kwargs):\n        \"\"\"\n        Override model_dump to include the _markdown private attribute in serialization.\n        \n        This override is necessary because:\n        1. PrivateAttr fields are excluded from serialization by default\n        2. We need to maintain backward compatibility by including the 'markdown' field\n           in the serialized output\n        3. We're transitioning from 'markdown_v2' to enhancing 'markdown' to hold\n           the same type of data\n        \n        Future developers: This method ensures that the markdown content is properly\n        serialized despite being stored in a private attribute. If the serialization\n        requirements change, this is where you would update the logic.","sourceCodeStart":5427,"sourceCodeEnd":5463,"githubUrl":"https://github.com/unclecode/crawl4ai/blob/7e801521428ee12509994d39151006f64055ebe3/deploy/docker/c4ai-code-context.md#L5427-L5463","documentation":"CrawlResult.fit_html used to expose the HTML remaining after content filtering. As with fit_markdown, the value now lives on the MarkdownGenerationResult under result.markdown.fit_html, and the old property deliberately raises AttributeError to break old usage loudly.","triggerScenarios":"Reading result.fit_html on a CrawlResult after upgrading; combining PruningContentFilter usage with code that persisted the filtered HTML.","commonSituations":"Post-upgrade breakage of pipelines that fed fit_html into a custom parser; legacy notebooks and integrations referencing the old attribute.","solutions":["Use result.markdown.fit_html instead","Verify a content filter was passed in CrawlerRunConfig so the field is populated"],"exampleFix":"// before\nhtml = result.fit_html\n// after\nhtml = result.markdown.fit_html\n","handlingStrategy":"type-guard","validationCode":"def get_fit_html(result):\n    md = getattr(result, \"markdown\", None)\n    return getattr(md, \"fit_html\", None) if md is not None else getattr(result, \"fit_html\", None)","typeGuard":"def has_fit_html(result) -> bool:\n    md = getattr(result, \"markdown\", None)\n    return md is not None and bool(getattr(md, \"fit_html\", None))","tryCatchPattern":"try:\n    fh = result.fit_html\nexcept AttributeError:\n    fh = result.markdown.fit_html\n","preventionTips":["Migrate fit_html reads to result.markdown.fit_html","Only expect fit_html when a content filter ran","Add a regression test asserting markdown.fit_html is a str (or None) after a filtered crawl"],"tags":["crawl4ai","deprecation","content-filter","fit-html"],"backgroundTag":null,"analyzedSha":"7e801521428ee12509994d39151006f64055ebe3","analyzedAt":"2026-08-14T20:46:20.673Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}