{"record":{"id":"ec4abf046684e5b3","repo":"unclecode/crawl4ai","slug":"at-least-one-of-include-internal-or-include-extern","errorCode":null,"errorMessage":"At least one of include_internal or include_external must be True","messagePattern":"At least one of include_internal or include_external must be True","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"crawl4ai/async_configs.py","lineNumber":1207,"sourceCode":"        self.exclude_patterns = exclude_patterns\n        self.concurrency = concurrency\n        self.timeout = timeout\n        self.max_links = max_links\n        self.query = query\n        self.score_threshold = score_threshold\n        self.verbose = verbose\n        \n        # Validation\n        if concurrency <= 0:\n            raise ValueError(\"concurrency must be positive\")\n        if timeout <= 0:\n            raise ValueError(\"timeout must be positive\")\n        if max_links <= 0:\n            raise ValueError(\"max_links must be positive\")\n        if score_threshold is not None and not (0.0 <= score_threshold <= 1.0):\n            raise ValueError(\"score_threshold must be between 0.0 and 1.0\")\n        if not include_internal and not include_external:\n            raise ValueError(\"At least one of include_internal or include_external must be True\")\n    \n    @staticmethod\n    def from_dict(config_dict: Dict[str, Any]) -> \"LinkPreviewConfig\":\n        \"\"\"Create LinkPreviewConfig from dictionary (for backward compatibility).\"\"\"\n        if not config_dict:\n            return None\n        \n        return LinkPreviewConfig(\n            include_internal=config_dict.get(\"include_internal\", True),\n            include_external=config_dict.get(\"include_external\", False),\n            include_patterns=config_dict.get(\"include_patterns\"),\n            exclude_patterns=config_dict.get(\"exclude_patterns\"),\n            concurrency=config_dict.get(\"concurrency\", 10),\n            timeout=config_dict.get(\"timeout\", 5),\n            max_links=config_dict.get(\"max_links\", 100),\n            query=config_dict.get(\"query\"),\n            score_threshold=config_dict.get(\"score_threshold\"),\n            verbose=config_dict.get(\"verbose\", False)","sourceCodeStart":1189,"sourceCodeEnd":1225,"githubUrl":"https://github.com/unclecode/crawl4ai/blob/7e801521428ee12509994d39151006f64055ebe3/crawl4ai/async_configs.py#L1189-L1225","documentation":"LinkPreviewConfig requires at least one of include_internal / include_external to be True. With both False there is no link set to preview, so the config would describe work that can never produce results — the constructor rejects it.","triggerScenarios":"LinkPreviewConfig(include_internal=False, include_external=False), typically when both flags come from config keys that default to False or are toggled off in pairs.","commonSituations":"Building the config from a dict where the user set internal=false intending external-only but also left external=false; feature-flag matrices that turn both off.","solutions":["Enable at least one category, e.g. LinkPreviewConfig(include_external=True)","When mapping user config, default one flag to True: include_internal=cfg.get('include_internal', True)","Skip constructing the config (pass None) when the user intends no previews at all"],"exampleFix":"// before\ncfg = LinkPreviewConfig(include_internal=False, include_external=False)\n// after\ncfg = LinkPreviewConfig(include_internal=False, include_external=True)","handlingStrategy":"validation","validationCode":"include_internal = user_cfg.get(\"include_internal\", True)\ninclude_external = user_cfg.get(\"include_external\", False)\nif not include_internal and not include_external:\n    include_external = True  # or refuse with a clear message\ncfg = LinkPreviewConfig(include_internal=include_internal, include_external=include_external)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Default one flag to True in config loaders","Reject all-off combinations at the API boundary with a helpful message"],"tags":["validation","configuration","link-preview"],"backgroundTag":null,"analyzedSha":"7e801521428ee12509994d39151006f64055ebe3","analyzedAt":"2026-08-14T20:46:20.673Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}