unclecode/crawl4ai · error · ValueError

link_preview_config must be LinkPreviewConfig object or dict

Error message

link_preview_config must be LinkPreviewConfig object or dict

What it means

CrawlerRunConfig accepts link_preview_config as None, a LinkPreviewConfig instance, or a plain dict (which it converts via LinkPreviewConfig.from_dict for backward compatibility). Any other type — string, tuple, list — raises this error.

Source

Thrown at crawl4ai/async_configs.py:1880

            )

        # Set default chunking strategy if None
        if self.chunking_strategy is None:
            self.chunking_strategy = RegexChunking()

        # Deep Crawl Parameters
        self.deep_crawl_strategy = deep_crawl_strategy
        
        # Link Extraction Parameters
        if link_preview_config is None:
            self.link_preview_config = None
        elif isinstance(link_preview_config, LinkPreviewConfig):
            self.link_preview_config = link_preview_config
        elif isinstance(link_preview_config, dict):
            # Convert dict to config object for backward compatibility
            self.link_preview_config = LinkPreviewConfig.from_dict(link_preview_config)
        else:
            raise ValueError("link_preview_config must be LinkPreviewConfig object or dict")
        
        # Virtual Scroll Parameters
        if virtual_scroll_config is None:
            self.virtual_scroll_config = None
        elif isinstance(virtual_scroll_config, VirtualScrollConfig):
            self.virtual_scroll_config = virtual_scroll_config
        elif isinstance(virtual_scroll_config, dict):
            # Convert dict to config object for backward compatibility
            self.virtual_scroll_config = VirtualScrollConfig.from_dict(virtual_scroll_config)
        else:
            raise ValueError("virtual_scroll_config must be VirtualScrollConfig object or dict")
        
        # URL Matching Parameters
        self.url_matcher = url_matcher
        self.match_mode = match_mode
        
        # Experimental Parameters
        self.experimental = experimental or {}

View on GitHub (pinned to 7e80152142)

Solutions

  1. Pass a dict of LinkPreviewConfig fields: link_preview_config={"include_external": True, "max_links": 10}
  2. Or construct the object: LinkPreviewConfig(include_external=True)
  3. If the value arrives as a JSON string, json.loads it first

Example fix

// before
cfg = CrawlerRunConfig(link_preview_config='{"max_links": 10}')
// after
import json
cfg = CrawlerRunConfig(link_preview_config=json.loads('{"max_links": 10}'))
Defensive patterns

Strategy: type-guard

Validate before calling

from crawl4ai.async_configs import LinkPreviewConfig

if isinstance(link_preview_config, str):
    import json
    link_preview_config = json.loads(link_preview_config)
assert link_preview_config is None or isinstance(link_preview_config, (LinkPreviewConfig, dict))

Type guard

def is_link_preview_config(v) -> bool:
    return v is None or isinstance(v, (LinkPreviewConfig, dict))

Prevention

When it happens

Trigger: Passing link_preview_config="enabled", a JSON string, a list of settings, or a config object from a different library/version.

Common situations: JSON config where the value parses as a string instead of an object; mixing crawl4ai versions where LinkPreviewConfig was imported from a relocated module.

Related errors


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