{"record":{"id":"3fd7174087d3a32d","repo":"unclecode/crawl4ai","slug":"setting-name-is-deprecated-self-unwanted-pr-3fd717","errorCode":null,"errorMessage":"Setting '{name}' is deprecated. {self._UNWANTED_PROPS[name]}","messagePattern":"Setting '(.+?)' is deprecated\\. (.+?)","errorType":"validation","errorClass":"AttributeError","httpStatus":null,"severity":"warning","filePath":"crawl4ai/content_filter_strategy.py","lineNumber":901,"sourceCode":"                colors={\n                    **AsyncLogger.DEFAULT_COLORS,\n                    LogLevel.INFO: LogColor.DIM_MAGENTA  # Dimmed purple for LLM ops\n                },\n            )\n        else:\n            self.logger = None\n\n        self.usages = []\n        self.total_usage = TokenUsage()\n    \n    def __setattr__(self, name, value):\n        \"\"\"Handle attribute setting.\"\"\"\n        # TODO: Planning to set properties dynamically based on the __init__ signature\n        sig = inspect.signature(self.__init__)\n        all_params = sig.parameters  # Dictionary of parameter names and their details\n\n        if name in self._UNWANTED_PROPS and value is not all_params[name].default:\n            raise AttributeError(f\"Setting '{name}' is deprecated. {self._UNWANTED_PROPS[name]}\")\n        \n        super().__setattr__(name, value)  \n        \n    def _get_cache_key(self, html: str, instruction: str) -> str:\n        \"\"\"Generate a unique cache key based on HTML and instruction\"\"\"\n        content = f\"{html}{instruction}\"\n        return hashlib.md5(content.encode()).hexdigest()\n\n    def _merge_chunks(self, text: str) -> List[str]:\n        \"\"\"Split text into chunks with overlap using char or word mode.\"\"\"\n        ov = int(self.chunk_token_threshold * self.overlap_rate)\n        sections = merge_chunks(\n            docs=[text],\n            target_size=self.chunk_token_threshold,\n            overlap=ov,\n            word_token_ratio=self.word_token_rate,\n        )\n        return sections","sourceCodeStart":883,"sourceCodeEnd":919,"githubUrl":"https://github.com/unclecode/crawl4ai/blob/7e801521428ee12509994d39151006f64055ebe3/crawl4ai/content_filter_strategy.py#L883-L919","documentation":"Filter strategies (LLM/PruneContentFilter base in content_filter_strategy.py) define _UNWANTED_PROPS — deprecated settings that must keep their constructor defaults. The __setattr__ hook inspects the __init__ signature and raises AttributeError whenever one of those names is assigned a non-default value, including from user code after construction. The message names the setting and its deprecation note from the dict.","triggerScenarios":"Constructing PruneContentFilter(..., some_deprecated_arg=X) with X != default, or setting filter.some_prop = value afterwards for any key in _UNWANTED_PROPS. Because __init__ itself goes through __setattr__, even constructor-time non-default values trip it.","commonSituations":"Upgrading crawl4ai after a setting was deprecated (e.g. old LLMExtractionStrategy/filter kwargs removed from the new API); copying old sample code that passes legacy options; programmatically copying attributes between filter objects.","solutions":["Remove the deprecated setting from your constructor call / stop assigning it; rely on the default.","Read _UNWANTED_PROPS[name] in the error message — it states the replacement or reason; migrate to the new API it points to.","If you must copy configs, skip keys present in _UNWANTED_PROPS or only assign values equal to the signature default."],"exampleFix":"# before\nfilter = PruneContentFilter(\n    chunk_token_threshold=512,\n    some_old_setting='x',        # in _UNWANTED_PROPS -> AttributeError\n)\n\n# after\nfilter = PruneContentFilter(chunk_token_threshold=512)  # deprecated setting removed","handlingStrategy":"validation","validationCode":"from crawl4ai.content_filter_strategy import PruneContentFilter\nunwanted = getattr(PruneContentFilter, '_UNWANTED_PROPS', {})\nkwargs = {k: v for k, v in kwargs.items() if k not in unwanted}","typeGuard":"def uses_only_supported_kwargs(cls, kwargs: dict) -> bool:\n    return not (set(kwargs) & set(getattr(cls, '_UNWANTED_PROPS', {})))","tryCatchPattern":"try:\n    f = PruneContentFilter(**kwargs)\nexcept AttributeError as e:\n    if 'is deprecated' in str(e):\n        kwargs = {k: v for k, v in kwargs.items() if k not in PruneContentFilter._UNWANTED_PROPS}\n        f = PruneContentFilter(**kwargs)\n    else:\n        raise","preventionTips":["After upgrading crawl4ai, diff your filter kwargs against _UNWANTED_PROPS.","Read the deprecation note in the error — it names the replacement API.","Keep filter construction centralized so migrations touch one place."],"tags":["deprecation","content-filter","configuration","api-change"],"backgroundTag":null,"analyzedSha":"7e801521428ee12509994d39151006f64055ebe3","analyzedAt":"2026-08-14T20:46:20.673Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}