{"record":{"id":"483efd9fedfcc1f7","repo":"D4Vinci/Scrapling","slug":"target-concurrency-must-be-higher-than-0","errorCode":null,"errorMessage":"`target_concurrency` must be higher than 0","messagePattern":"`target_concurrency` must be higher than 0","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"scrapling/spiders/throttle.py","lineNumber":51,"sourceCode":"    servers and backs off on slow or hostile ones.\"\"\"\n\n    def __init__(\n        self,\n        start_delay: float = 5.0,\n        max_delay: float = 60.0,\n        target_concurrency: float = 1.0,\n        block_backoff: bool = True,\n    ):\n        \"\"\"\n        :param start_delay: The delay used for the first request to a domain.\n        :param max_delay: The highest delay the throttle is allowed to reach.\n        :param target_concurrency: How many requests the spider aims to have in flight per domain. The engine\n            passes the spider's `concurrent_requests_per_domain` here, or 1 when it's unlimited.\n        :param block_backoff: Double the delay of a domain whenever it blocks us, or wait what its `Retry-After`\n            header asks for.\n        \"\"\"\n        if target_concurrency <= 0:\n            raise ValueError(\"`target_concurrency` must be higher than 0\")\n        if max_delay < start_delay:\n            raise ValueError(\"`autothrottle_max_delay` can't be lower than `autothrottle_start_delay`\")\n\n        self.start_delay = start_delay\n        self.max_delay = max_delay\n        self.target_concurrency = target_concurrency\n        self.block_backoff = block_backoff\n        self.delays: Dict[str, float] = {}\n\n    def delay_for(self, domain: str, floor: float = 0.0) -> float:\n        \"\"\"Return the current delay for a domain, starting it at `start_delay` the first time.\n\n        :param domain: The domain the request belongs to.\n        :param floor: The lowest delay allowed, which is the spider's own delay for this domain.\n        \"\"\"\n        if domain not in self.delays:\n            self.delays[domain] = min(max(floor, self.start_delay), self.max_delay)\n        return self.delays[domain]","sourceCodeStart":33,"sourceCodeEnd":69,"githubUrl":"https://github.com/D4Vinci/Scrapling/blob/5d213a2d4764002bfc4fed33c32fe09fa8b0bf7f/scrapling/spiders/throttle.py#L33-L69","documentation":"AutoThrottle validates that target_concurrency > 0 at construction. The engine passes the spider's concurrent_requests_per_domain here (or 1 when unlimited), so a zero or negative concurrency setting surfaces as this ValueError.","triggerScenarios":"Setting concurrent_requests_per_domain = 0 (or a negative number) on the spider, which the engine forwards as target_concurrency to AutoThrottle; constructing AutoThrottle directly with target_concurrency=0.","commonSituations":"Using 0 to mean 'unlimited' — in this library unlimited is expressed differently and 0 is rejected; config files that default concurrency to 0; arithmetic that computes concurrency from data and can produce 0.","solutions":["Set concurrent_requests_per_domain to a positive value (e.g. 1 for polite, higher for aggressive crawling)","If unlimited per-domain concurrency is desired, leave the setting unset/None so the engine passes 1 to the throttle with unlimited in-flight requests","When building AutoThrottle yourself, pass max(1, concurrency)"],"exampleFix":"// before\nclass MySpider(Spider):\n    concurrent_requests_per_domain = 0  # rejected\n\n// after\nclass MySpider(Spider):\n    concurrent_requests_per_domain = 4","handlingStrategy":"validation","validationCode":"concurrency = max(1, concurrency)  # before assigning to the spider/throttle","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use positive integers for concurrent_requests_per_domain","Leave per-domain concurrency unset for unlimited rather than using 0","Validate computed concurrency configs in tests"],"tags":["throttle","configuration","validation"],"backgroundTag":null,"analyzedSha":"5d213a2d4764002bfc4fed33c32fe09fa8b0bf7f","analyzedAt":"2026-08-14T22:23:09.440Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}