unclecode/crawl4ai · error · ValueError
timeout must be positive
Error message
timeout must be positive
What it means
LinkPreviewConfig requires a positive timeout because it is passed to per-request fetch timeouts (e.g. asyncio.wait_for). A zero or negative timeout would either fail immediately or be interpreted as no-wait, so it is rejected at construction time.
Source
Thrown at crawl4ai/async_configs.py:1201
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),
include_patterns=config_dict.get("include_patterns"),
exclude_patterns=config_dict.get("exclude_patterns"),View on GitHub (pinned to 7e80152142)
Solutions
- Set timeout in seconds, e.g. LinkPreviewConfig(timeout=30)
- Validate externally sourced values before constructing: raise/config-default if value <= 0
- Do not use timeout=0 to mean 'no timeout' — this library has no such opt-out for previews
Example fix
// before
cfg = LinkPreviewConfig(timeout=cfg_json.get("timeout", 0))
// after
cfg = LinkPreviewConfig(timeout=cfg_json.get("timeout", 30)) Defensive patterns
Strategy: validation
Validate before calling
timeout = timeout if isinstance(timeout, (int, float)) and timeout > 0 else 30 cfg = LinkPreviewConfig(timeout=timeout)
Prevention
- Document timeout as seconds in your config schema
- Treat missing/invalid timeout as a default, not 0
When it happens
Trigger: LinkPreviewConfig(timeout=0) or a negative number; unit mismatch such as passing microseconds or 0.5 when an int number of seconds was intended via a config pipeline.
Common situations: Reading timeout from a JSON/YAML config where the field is missing and coerced to 0; passing timeout in the wrong unit after porting code from another library.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- concurrency must be positive
- max_links must be positive
- score_threshold must be between 0.0 and 1.0
- At least one of include_internal or include_external must be
- link_preview_config must be LinkPreviewConfig object or dict
AI-assisted analysis of unclecode/crawl4ai@7e80152142 (2026-08-14).
Data as JSON: /api/errors/07da4edd29d4d03f.
Report an issue: GitHub.