{"record":{"id":"09aff57dce1eaa64","repo":"bytedance/deer-flow","slug":"openviking-health-check-returned-an-unhealthy-resp","errorCode":null,"errorMessage":"OpenViking health check returned an unhealthy response","messagePattern":"OpenViking health check returned an unhealthy response","errorType":"exception","errorClass":"MemoryManagerError","httpStatus":null,"severity":"critical","filePath":"backend/packages/harness/deerflow/agents/memory/backends/openviking/openviking_manager.py","lineNumber":281,"sourceCode":"        )\n\n    def warm(self) -> bool | None:\n        if not self._begin_operation():\n            return False\n        try:\n            try:\n                health = getattr(self._client, \"health\", None)\n                healthy = bool(health()) if callable(health) else True\n            except Exception:\n                if self._config.startup_policy == \"fail_fast\":\n                    raise\n                logger.warning(\n                    \"OpenViking startup validation failed; memory will run in degraded mode\",\n                    exc_info=True,\n                )\n                return False\n            if not healthy and self._config.startup_policy == \"fail_fast\":\n                raise MemoryManagerError(\"OpenViking health check returned an unhealthy response\")\n            if not healthy:\n                logger.warning(\"OpenViking health check returned unhealthy; memory will run in degraded mode\")\n            return healthy\n        finally:\n            self._end_operation()\n\n    def shutdown_flush(self, timeout: float) -> bool:\n        \"\"\"Stop new work, drain accepted calls, and close owned resources.\"\"\"\n\n        deadline = time.monotonic() + max(0.0, timeout)\n        with self._lifecycle:\n            self._closed = True\n            self._close_requested = True\n            while self._active_operations:\n                remaining = deadline - time.monotonic()\n                if remaining <= 0:\n                    return False\n                self._lifecycle.wait(remaining)","sourceCodeStart":263,"sourceCodeEnd":299,"githubUrl":"https://github.com/bytedance/deer-flow/blob/1dd6ba1acb03700589994b0366c5d1c7d05e2eff/backend/packages/harness/deerflow/agents/memory/backends/openviking/openviking_manager.py#L263-L299","documentation":"During startup validation, OpenVikingMemoryManager calls the SDK client's health() and, if it returns a falsy result while startup_policy is 'fail_fast' (the default), raises MemoryManagerError. This is a deliberate fail-fast: an unavailable OpenViking service should abort rather than silently run without memory. Note the distinction: an exception from health() under fail_fast re-raises the original exception; this specific message means health() was callable, returned, and reported unhealthy.","triggerScenarios":"OpenVikingConfig.startup_policy == 'fail_fast' (default) and the OpenViking service at base_url answers its health endpoint as unhealthy — service up but degraded, wrong build, or a proxy returning an unhealthy status. Happens during manager startup validation, i.e. Gateway boot / agent rebuild.","commonSituations":"OpenViking container starting but failing its own readiness (schema migration pending, dependency down), or base_url pointing at the wrong service/port that responds with an error payload to the health call.","solutions":["Check the OpenViking service is actually healthy: query its health endpoint at the configured base_url directly","Fix the service (restart it, check its logs, wait for migrations) and restart the Gateway","If degraded-mode startup is acceptable, set memory.backend_config.startup_policy: warn — memory recall will then be skipped/logged while the service is unhealthy"],"exampleFix":"# before (config.yaml)\nmemory:\n  manager_class: openviking\n  backend_config:\n    startup_policy: fail_fast   # Gateway refuses to start while OpenViking is unhealthy\n\n# after (accept degraded boot)\nmemory:\n  manager_class: openviking\n  backend_config:\n    startup_policy: warn","handlingStrategy":"fallback","validationCode":"# Pre-startup probe: verify OpenViking answers before booting the Gateway with fail_fast\nimport urllib.request\nwith urllib.request.urlopen(f\"{base_url}/health\", timeout=5) as resp:\n    assert resp.status == 200, f\"OpenViking unhealthy: HTTP {resp.status}\"","typeGuard":null,"tryCatchPattern":"from deerflow.agents.memory.manager import MemoryManagerError\ntry:\n    manager = OpenVikingMemoryManager.from_config(cfg)\nexcept MemoryManagerError as exc:\n    if \"unhealthy\" in str(exc):\n        deploy_degraded()  # or wait/retry after fixing the OpenViking service\n    raise","preventionTips":["Put an OpenViking health probe in the deployment readiness path (compose depends_on healthcheck / K8s initContainer)","Choose startup_policy: warn for environments where the Gateway must boot even if memory is down","Keep fail_fast in production to surface service outages at boot instead of via missing memory"],"tags":["openviking","health-check","startup","memory"],"backgroundTag":null,"analyzedSha":"1dd6ba1acb03700589994b0366c5d1c7d05e2eff","analyzedAt":"2026-08-14T21:20:34.804Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}