{"record":{"id":"92d5ab64c86562bb","repo":"zylon-ai/private-gpt","slug":"api-base-url-and-poll-interval-must-be-provided-in","errorCode":null,"errorMessage":"API base URL and poll interval must be provided in async mode","messagePattern":"API base URL and poll interval must be provided in async mode","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"private_gpt/components/readers/docling/api_clients.py","lineNumber":397,"sourceCode":"    base_url: str = Field(description=\"Base URL for the Docling API\")\n    poll_interval: float = Field(description=\"Polling interval in seconds\", default=5.0)\n    poll_timeout: float | None = Field(\n        description=\"Polling timeout in seconds\", default=None\n    )\n\n    def __init__(\n        self,\n        settings: DoclingConfig,\n        api_base: str | None = None,\n        poll_interval: float | None = None,\n        poll_timeout: float | None = None,\n    ):\n        api_base = api_base or settings.api_base\n        poll_interval = poll_interval or settings.pool_interval\n        poll_timeout = poll_timeout or settings.pool_timeout\n\n        if not api_base or not poll_interval:\n            raise ValueError(\n                \"API base URL and poll interval must be provided in async mode\"\n            )\n\n        super().__init__(\n            docling_settings=settings,\n            base_url=_build_api_base_url(\n                api_base or settings.api_base, settings.api_version\n            ),\n            poll_interval=poll_interval or settings.pool_interval,\n            poll_timeout=poll_timeout or settings.pool_timeout,\n        )\n\n    @retry(is_async=True, tries=_MAX_RETRIES, jitter=_JITTER, logger=logger)\n    async def _submit_task(\n        self, file_name: str, file_bytes: bytes, **kwargs: Any\n    ) -> str:\n        file_base64 = base64.b64encode(file_bytes).decode(\"utf-8\")\n        headers = _build_request_headers(self.docling_settings)","sourceCodeStart":379,"sourceCodeEnd":415,"githubUrl":"https://github.com/zylon-ai/private-gpt/blob/4a030776a31a901ad80b1bf4d7faa2c1a367efbb/private_gpt/components/readers/docling/api_clients.py#L379-L415","documentation":"Raised by AsyncDoclingClient.__init__ when neither the constructor arguments nor the Docling settings provide an API base URL and a poll interval. The async client drives Docling's task-based API by submitting a job and repeatedly polling /status/poll/{task_id}, so both values are structurally required before any request can be made. Note the constructor uses `or` fallbacks against settings.docling.api_base and settings.docling.pool_interval, so an empty string or 0 passed explicitly also falls through to settings, and the check fires only if the settings value is also falsy.","triggerScenarios":"Instantiating AsyncDoclingClient(settings) where settings.docling.api_base or settings.docling.pool_interval is unset/None/empty (e.g., a settings.yaml that overrides the docling block and drops pool_interval), or passing api_base='' / poll_interval=0 explicitly while settings are also empty. Happens at client construction time, before any network call.","commonSituations":"Custom settings.yaml that sets only docling.api_base but omits docling.pool_interval (the default only applies when the whole docling block is untouched); env-var-driven configs that blank out values; code that builds DoclingConfig programmatically with only some fields; copy-paste from LocalDoclingClient examples where polling is not needed.","solutions":["Set both values in settings.yaml under docling: api_base: http://localhost:5001 and pool_interval: 5 (or your server URL).","Or pass them explicitly: AsyncDoclingClient(settings, api_base='http://localhost:5001', poll_interval=5.0).","If building DoclingConfig programmatically, ensure pool_interval is set (remember the field is named pool_interval, not poll_interval, in settings).","Note poll_timeout is optional: leaving pool_timeout unset means the client polls forever (the while loop condition `not self.poll_timeout` never breaks), so set docling.pool_timeout if you want bounded waits."],"exampleFix":"# before\nclient = AsyncDoclingClient(settings)  # settings.docling.pool_interval is None\n\n# after (settings.yaml)\n# docling:\n#   api_base: http://localhost:5001\n#   pool_interval: 5\n#   pool_timeout: 600\n# or in code\nclient = AsyncDoclingClient(settings, api_base='http://localhost:5001', poll_interval=5.0, poll_timeout=600.0)","handlingStrategy":"validation","validationCode":"from private_gpt.components.readers.docling.api_clients import AsyncDoclingClient\n\ndef assert_async_docling_ready(cfg) -> None:\n    if not cfg.api_base:\n        raise SystemExit(\"settings.docling.api_base is required for the async Docling client\")\n    if not cfg.pool_interval:\n        raise SystemExit(\"settings.docling.pool_interval is required for the async Docling client\")\n\nassert_async_docling_ready(settings().docling)","typeGuard":null,"tryCatchPattern":"try:\n    client = AsyncDoclingClient(docling_cfg)\nexcept ValueError as e:\n    if \"async mode\" in str(e):\n        # configuration problem: fix settings, do not retry\n        raise ConfigurationError(str(e)) from e\n    raise","preventionTips":["Add a startup check that settings.docling.api_base and docling.pool_interval are truthy before constructing AsyncDoclingClient.","Remember settings field names use pool_interval/pool_timeout while constructor args use poll_interval/poll_timeout.","Set pool_timeout explicitly unless you intend infinite polling."],"tags":["docling","configuration","initialization","async"],"backgroundTag":null,"analyzedSha":"4a030776a31a901ad80b1bf4d7faa2c1a367efbb","analyzedAt":"2026-08-15T03:51:26.951Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}