unclecode/crawl4ai · warning · AttributeError

The 'fit_html' attribute is deprecated and has been removed.

Error message

The 'fit_html' attribute is deprecated and has been removed. Please use 'markdown.fit_html' instead.

What it means

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.

Source

Thrown at crawl4ai/models.py:242:5445

            """
        )
    
    @property
    def fit_markdown(self):
        """
        Deprecated property that raises an AttributeError when accessed.
        """
        raise AttributeError(
            "The 'fit_markdown' attribute is deprecated and has been removed. "
            "Please use 'markdown.fit_markdown' instead."
        )
    
    @property
    def fit_html(self):
        """
        Deprecated property that raises an AttributeError when accessed.
        """
        raise AttributeError(
            "The 'fit_html' attribute is deprecated and has been removed. "
            "Please use 'markdown.fit_html' instead."
        )

    def model_dump(self, *args, **kwargs):
        """
        Override model_dump to include the _markdown private attribute in serialization.
        
        This override is necessary because:
        1. PrivateAttr fields are excluded from serialization by default
        2. We need to maintain backward compatibility by including the 'markdown' field
           in the serialized output
        3. We're transitioning from 'markdown_v2' to enhancing 'markdown' to hold
           the same type of data
        
        Future developers: This method ensures that the markdown content is properly
        serialized despite being stored in a private attribute. If the serialization
        requirements change, this is where you would update the logic.

View on GitHub (pinned to 7e80152142)

Solutions

  1. Use result.markdown.fit_html instead
  2. Verify a content filter was passed in CrawlerRunConfig so the field is populated

Example fix

// before
html = result.fit_html
// after
html = result.markdown.fit_html
Defensive patterns

Strategy: type-guard

Validate before calling

def get_fit_html(result):
    md = getattr(result, "markdown", None)
    return getattr(md, "fit_html", None) if md is not None else getattr(result, "fit_html", None)

Type guard

def has_fit_html(result) -> bool:
    md = getattr(result, "markdown", None)
    return md is not None and bool(getattr(md, "fit_html", None))

Try / catch

try:
    fh = result.fit_html
except AttributeError:
    fh = result.markdown.fit_html

Prevention

When it happens

Trigger: Reading result.fit_html on a CrawlResult after upgrading; combining PruningContentFilter usage with code that persisted the filtered HTML.

Common situations: Post-upgrade breakage of pipelines that fed fit_html into a custom parser; legacy notebooks and integrations referencing the old attribute.

Related errors


AI-assisted analysis of unclecode/crawl4ai@7e80152142 (2026-08-14). Data as JSON: /api/errors/a0b241f75d129175. Report an issue: GitHub.