{"record":{"id":"f741ab2e4b1f4d42","repo":"bytedance/deer-flow","slug":"honcho-backend-api-key-over-plain-http-requires-b","errorCode":null,"errorMessage":"Honcho backend: api_key over plain http requires backend_config.allow_insecure_http: true (the key would be sent unencrypted). Use https, or set the opt-in for local development.","messagePattern":"Honcho backend: api_key over plain http requires backend_config\\.allow_insecure_http: true \\(the key would be sent unencrypted\\)\\. Use https, or set the opt-in for local development\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"backend/packages/harness/deerflow/agents/memory/backends/honcho/config.py","lineNumber":60,"sourceCode":"    user_peer_overrides: dict[str, str] = field(default_factory=dict)\n    assistant_peer: str = \"deerflow\"\n    timeout_seconds: float = 10.0\n    connect_timeout_seconds: float = 3.0\n    message_char_limit: int = 8000\n    max_injection_chars: int = 6000\n    allow_insecure_http: bool = False\n    read_fail_closed: bool = False\n    storage_path: str = \"\"\n\n    @classmethod\n    def from_backend_config(cls, backend_config: dict[str, Any] | None) -> HonchoConfig:\n        cfg = dict(backend_config or {})\n        failure_policy = cfg.get(\"failure_policy\") or {}\n        base_url = str(cfg.get(\"base_url\", \"http://localhost:8000\")).rstrip(\"/\")\n        api_key = cfg.get(\"api_key\") or None\n        allow_insecure = bool(cfg.get(\"allow_insecure_http\", False))\n        if api_key and base_url.startswith(\"http://\") and not allow_insecure:\n            raise ValueError(\"Honcho backend: api_key over plain http requires backend_config.allow_insecure_http: true (the key would be sent unencrypted). Use https, or set the opt-in for local development.\")\n        return cls(\n            base_url=base_url,\n            api_key=api_key,\n            workspace_prefix=str(cfg.get(\"workspace_prefix\", \"deerflow-u-\")),\n            workspace_overrides=_parse_override_map(cfg, \"workspace_overrides\"),\n            user_peer_overrides=_parse_override_map(cfg, \"user_peer_overrides\"),\n            assistant_peer=str(cfg.get(\"assistant_peer\", \"deerflow\")),\n            timeout_seconds=float(cfg.get(\"timeout_seconds\", 10.0)),\n            connect_timeout_seconds=float(cfg.get(\"connect_timeout_seconds\", 3.0)),\n            message_char_limit=int(cfg.get(\"message_char_limit\", 8000)),\n            max_injection_chars=int(cfg.get(\"max_injection_chars\", 6000)),\n            allow_insecure_http=allow_insecure,\n            read_fail_closed=str(failure_policy.get(\"read\", \"\")).lower() == \"fail_closed\",\n            storage_path=str(cfg.get(\"storage_path\") or \"\"),\n        )\n","sourceCodeStart":42,"sourceCodeEnd":76,"githubUrl":"https://github.com/bytedance/deer-flow/blob/1dd6ba1acb03700589994b0366c5d1c7d05e2eff/backend/packages/harness/deerflow/agents/memory/backends/honcho/config.py#L42-L76","documentation":"Raised by HonchoConfig.from_backend_config when an api_key is configured while base_url starts with http:// and allow_insecure_http is not true. The API key would be sent unencrypted in the Authorization header on every request, so the config parser rejects the combination unless the operator explicitly opts in for trusted local development (self-hosted Honcho commonly runs auth-less over plain HTTP, which stays allowed without an api_key).","triggerScenarios":"memory.backend_config with manager_class: honcho, api_key set (e.g. Honcho Cloud key) and base_url: http://localhost:8000 or any http:// URL, without allow_insecure_http: true. HonchoConfig.from_backend_config raises before any HTTP call is made.","commonSituations":"Pointing the default local base_url (http://localhost:8000) at a remote/managed Honcho that requires a key; starting with local HTTP and later adding a key without switching to https; corporate proxy that rewrites https to http.","solutions":["Switch base_url to the https:// endpoint of your Honcho instance (e.g. https://demo.honcho.dev) — the key then travels encrypted","Remove api_key if the target Honcho is self-hosted auth-less over plain HTTP (the common local setup)","Only for trusted local development: keep http:// and add allow_insecure_http: true to backend_config"],"exampleFix":"# before (config.yaml)\nmemory:\n  manager_class: honcho\n  backend_config:\n    base_url: http://localhost:8000\n    api_key: \"${HONCHO_API_KEY}\"\n\n# after\nmemory:\n  manager_class: honcho\n  backend_config:\n    base_url: https://demo.honcho.dev\n    api_key: \"${HONCHO_API_KEY}\"","handlingStrategy":"validation","validationCode":"from urllib.parse import urlsplit\n\ndef honcho_transport_ok(backend_config: dict) -> bool:\n    base_url = str(backend_config.get(\"base_url\", \"http://localhost:8000\"))\n    has_key = bool(backend_config.get(\"api_key\"))\n    allows_insecure = bool(backend_config.get(\"allow_insecure_http\", False))\n    return not (has_key and urlsplit(base_url).scheme == \"http\" and not allows_insecure)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Pair any api_key with an https:// base_url by convention; never ship http + key without the explicit opt-in","Keep allow_insecure_http confined to local dev configs; strip it in production templates","If a proxy terminates TLS, point base_url at the https listener, not the plain-http backend"],"tags":["security","config","honcho","http","memory"],"backgroundTag":null,"analyzedSha":"1dd6ba1acb03700589994b0366c5d1c7d05e2eff","analyzedAt":"2026-08-14T21:20:34.804Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}