unclecode/crawl4ai · error · ValueError

concurrency must be positive

Error message

concurrency must be positive

What it means

LinkPreviewConfig validates that concurrency is a positive number because it sizes the worker pool for concurrently fetching link previews. Zero or negative concurrency has no meaningful execution semantics, so construction fails immediately.

Solutions

  1. Set concurrency to a positive value; 5–20 is typical for link-preview fetching
  2. If you meant to disable link previews, pass link_preview_config=None to CrawlerRunConfig instead of zeroing fields
  3. Guard computed values: max(1, computed_concurrency)

Example fix

// before
cfg = LinkPreviewConfig(concurrency=workers - cores)  # can be <= 0
// after
cfg = LinkPreviewConfig(concurrency=max(1, workers - cores))
Defensive patterns

Strategy: validation

Validate before calling

concurrency = max(1, int(concurrency or 5))
cfg = LinkPreviewConfig(concurrency=concurrency)

Prevention

When it happens

Trigger: LinkPreviewConfig(concurrency=0), a negative value, or computing concurrency from a formula (e.g. desired_parallelism - existing) that evaluates to <= 0.

Common situations: Deriving concurrency from CPU count or a config file where the key is absent and defaults to 0; disabling previews by setting concurrency=0 instead of omitting the config.

Related errors


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

Appendix: source

Thrown at crawl4ai/async_configs.py:1199

            max_links: Maximum number of links to process (prevents overload)
            query: Query string for BM25 contextual scoring (optional)
            score_threshold: Minimum relevance score to include links (0.0-1.0, optional)
            verbose: Show detailed progress during extraction
        """
        self.include_internal = include_internal
        self.include_external = include_external
        self.include_patterns = include_patterns
        self.exclude_patterns = exclude_patterns
        self.concurrency = concurrency
        self.timeout = timeout
        self.max_links = max_links
        self.query = query
        self.score_threshold = score_threshold
        self.verbose = verbose
        
        # Validation
        if concurrency <= 0:
            raise ValueError("concurrency must be positive")
        if timeout <= 0:
            raise ValueError("timeout must be positive")
        if max_links <= 0:
            raise ValueError("max_links must be positive")
        if score_threshold is not None and not (0.0 <= score_threshold <= 1.0):
            raise ValueError("score_threshold must be between 0.0 and 1.0")
        if not include_internal and not include_external:
            raise ValueError("At least one of include_internal or include_external must be True")
    
    @staticmethod
    def from_dict(config_dict: Dict[str, Any]) -> "LinkPreviewConfig":
        """Create LinkPreviewConfig from dictionary (for backward compatibility)."""
        if not config_dict:
            return None
        
        return LinkPreviewConfig(
            include_internal=config_dict.get("include_internal", True),
            include_external=config_dict.get("include_external", False),

View on GitHub (pinned to 7e80152142)