unclecode/crawl4ai · warning · AttributeError

The 'fit_markdown' attribute is deprecated and has been remo

Error message

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

What it means

CrawlResult.fit_markdown used to return the PruningContentFilter-filtered ('fit') markdown directly on the result object. In the new API the fit output lives inside the MarkdownGenerationResult returned by result.markdown, so the old property is a tombstone that raises AttributeError pointing you at markdown.fit_markdown.

Source

Thrown at crawl4ai/models.py:232:5435

        deprecated and they should use 'markdown' instead.
        """
        raise AttributeError(
            "The 'markdown_v2' attribute is deprecated and has been removed. "
            """Please use 'markdown' instead, which now returns a MarkdownGenerationResult, with
            following properties:
            - raw_markdown: The raw markdown string
            - markdown_with_citations: The markdown string with citations
            - references_markdown: The markdown string with references
            - fit_markdown: The markdown string with fit text
            """
        )
    
    @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.
        

View on GitHub (pinned to 7e80152142)

Solutions

  1. Use result.markdown.fit_markdown instead
  2. Make sure a content filter is actually configured (e.g. CrawlerRunConfig(content_filter=PruningContentFilter(...), cache_mode=...)) — otherwise markdown.fit_markdown may be empty

Example fix

// before
fit = result.fit_markdown
// after
fit = result.markdown.fit_markdown
Defensive patterns

Strategy: type-guard

Validate before calling

def get_fit(result):
    md = getattr(result, "markdown", None)
    if md is not None:
        return getattr(md, "fit_markdown", None) or getattr(md, "raw_markdown", "")
    return getattr(result, "fit_markdown", "")

Type guard

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

Try / catch

try:
    fit = result.fit_markdown
except AttributeError:
    fit = result.markdown.fit_markdown

Prevention

When it happens

Trigger: Reading result.fit_markdown after a crawl where a content filter (e.g. PruningContentFilter) was configured in CrawlerRunConfig; older code written before the markdown refactor.

Common situations: Upgrading crawl4ai and hitting the markdown refactor; RAG pipelines that stored fit_markdown for chunking; examples from blog posts targeting the old attribute layout.

Related errors


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