infiniflow/ragflow · error · SandboxProviderConfigError

Failed to reach Tenki API: {exc}

Error message

Failed to reach Tenki API: {exc}

What it means

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.

Source

Thrown at agent/sandbox/providers/tenki.py:416

    def _create_client(self):
        tenki = _get_tenki_module()
        # Bound control-plane requests (who_am_i, create) so a slow or
        # unreachable API cannot block initialize()/create_instance() forever.
        kwargs: dict[str, Any] = {"auth_token": self.api_key, "timeout": float(self.timeout)}
        if self.base_url:
            kwargs["base_url"] = self.base_url
        return tenki.Client(**kwargs)

    def _assert_connectivity(self) -> None:
        client = self._client or self._create_client()
        errors = self._tenki_errors()
        try:
            client.who_am_i()
        except errors.UnauthorizedError as exc:
            raise SandboxProviderConfigError("Tenki authentication failed: check the API key.") from exc
        except Exception as exc:
            raise SandboxProviderConfigError(f"Failed to reach Tenki API: {exc}") from exc

    def _prepare_script(self, sandbox, remote_work_dir: str, language: str, code: str, args_json: str) -> tuple[str, list[str]]:
        if language == "python":
            script_name = "main.py"
            script_content = build_python_wrapper(code, args_json)
            executable = "python3"
        elif language in {"javascript", "nodejs"}:
            script_name = "main.js"
            script_content = build_javascript_wrapper(code, args_json)
            executable = "node"
        else:
            raise RuntimeError(f"Unsupported language for Tenki provider: {language}")

        script_path = posixpath.join(remote_work_dir, script_name)
        sandbox.fs.write_text(script_path, script_content)
        return script_path, [executable, script_path]

    def _validate_output_size(self, stdout: str, stderr: str) -> None:

View on GitHub (pinned to 554fb1133a)

Solutions

  1. curl the base_url (or default Tenki endpoint) from the same host/container to verify reachability and TLS.
  2. Fix or remove base_url in the config; open firewall/proxy egress for the Tenki API domain.
  3. If the API is briefly down, retry initialize() with backoff at startup.

Example fix

# before
provider.initialize({"api_key": key, "base_url": "tenki.api.internal"})  # no scheme, unreachable

# after
provider.initialize({"api_key": key, "base_url": "https://tenki.api.internal"})  # verify with curl first
Defensive patterns

Strategy: validation

Validate before calling

import socket
from urllib.parse import urlparse
u = urlparse(base_url or "https://api.tenki.io")
assert u.scheme in ("http", "https") and u.netloc, "bad base_url"
socket.getaddrinfo(u.hostname, u.port or 443)  # DNS check before initialize()

Try / catch

try:
    provider.initialize(config)
except SandboxProviderConfigError as exc:
    if "Failed to reach" in str(exc):
        retry_initialize_with_backoff(provider, config)  # transient outage
    else:
        raise

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of infiniflow/ragflow@554fb1133a (2026-08-15). Data as JSON: /api/errors/a3755d4281681811. Report an issue: GitHub.