{"record":{"id":"a3755d4281681811","repo":"infiniflow/ragflow","slug":"failed-to-reach-tenki-api-exc","errorCode":null,"errorMessage":"Failed to reach Tenki API: {exc}","messagePattern":"Failed to reach Tenki API: (.+?)","errorType":"exception","errorClass":"SandboxProviderConfigError","httpStatus":null,"severity":"error","filePath":"agent/sandbox/providers/tenki.py","lineNumber":416,"sourceCode":"\n    def _create_client(self):\n        tenki = _get_tenki_module()\n        # Bound control-plane requests (who_am_i, create) so a slow or\n        # unreachable API cannot block initialize()/create_instance() forever.\n        kwargs: dict[str, Any] = {\"auth_token\": self.api_key, \"timeout\": float(self.timeout)}\n        if self.base_url:\n            kwargs[\"base_url\"] = self.base_url\n        return tenki.Client(**kwargs)\n\n    def _assert_connectivity(self) -> None:\n        client = self._client or self._create_client()\n        errors = self._tenki_errors()\n        try:\n            client.who_am_i()\n        except errors.UnauthorizedError as exc:\n            raise SandboxProviderConfigError(\"Tenki authentication failed: check the API key.\") from exc\n        except Exception as exc:\n            raise SandboxProviderConfigError(f\"Failed to reach Tenki API: {exc}\") from exc\n\n    def _prepare_script(self, sandbox, remote_work_dir: str, language: str, code: str, args_json: str) -> tuple[str, list[str]]:\n        if language == \"python\":\n            script_name = \"main.py\"\n            script_content = build_python_wrapper(code, args_json)\n            executable = \"python3\"\n        elif language in {\"javascript\", \"nodejs\"}:\n            script_name = \"main.js\"\n            script_content = build_javascript_wrapper(code, args_json)\n            executable = \"node\"\n        else:\n            raise RuntimeError(f\"Unsupported language for Tenki provider: {language}\")\n\n        script_path = posixpath.join(remote_work_dir, script_name)\n        sandbox.fs.write_text(script_path, script_content)\n        return script_path, [executable, script_path]\n\n    def _validate_output_size(self, stdout: str, stderr: str) -> None:","sourceCodeStart":398,"sourceCodeEnd":434,"githubUrl":"https://github.com/infiniflow/ragflow/blob/554fb1133ac3861732235ad9c377eb5e0a770665/agent/sandbox/providers/tenki.py#L398-L434","documentation":"Raised by _assert_connectivity() when the who_am_i() probe fails with any non-auth error during initialize(). The Tenki API could not be reached at all — DNS, TLS, network, wrong base_url — or returned an unexpected server error; it is wrapped in SandboxProviderConfigError so startup fails fast.","triggerScenarios":"initialize() with a base_url that is mistyped, lacks the scheme, or points at a proxy/firewalled endpoint; no outbound network from the RAGFlow host; Tenki API outage returning 5xx.","commonSituations":"Self-hosted deployments behind egress-restricted networks, on-prem proxies not honored by the SDK, typo'd base_url in docker-compose/service configs, or transient Tenki-side outages at boot time.","solutions":["curl the base_url (or default Tenki endpoint) from the same host/container to verify reachability and TLS.","Fix or remove base_url in the config; open firewall/proxy egress for the Tenki API domain.","If the API is briefly down, retry initialize() with backoff at startup."],"exampleFix":"# before\nprovider.initialize({\"api_key\": key, \"base_url\": \"tenki.api.internal\"})  # no scheme, unreachable\n\n# after\nprovider.initialize({\"api_key\": key, \"base_url\": \"https://tenki.api.internal\"})  # verify with curl first","handlingStrategy":"validation","validationCode":"import socket\nfrom urllib.parse import urlparse\nu = urlparse(base_url or \"https://api.tenki.io\")\nassert u.scheme in (\"http\", \"https\") and u.netloc, \"bad base_url\"\nsocket.getaddrinfo(u.hostname, u.port or 443)  # DNS check before initialize()","typeGuard":null,"tryCatchPattern":"try:\n    provider.initialize(config)\nexcept SandboxProviderConfigError as exc:\n    if \"Failed to reach\" in str(exc):\n        retry_initialize_with_backoff(provider, config)  # transient outage\n    else:\n        raise","preventionTips":["Always include the scheme (https://) in base_url.","Verify egress/proxy rules from the RAGFlow host to the Tenki API before deploying.","Treat reachability errors at boot as retryable, auth errors as fatal."],"tags":["network","connectivity","config","tenki"],"backgroundTag":null,"analyzedSha":"554fb1133ac3861732235ad9c377eb5e0a770665","analyzedAt":"2026-08-15T09:20:16.380Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}