{"record":{"id":"0e0416b255b75b40","repo":"bytedance/deer-flow","slug":"mem0-base-url-must-be-an-absolute-http-or-https","errorCode":null,"errorMessage":"mem0 base_url must be an absolute http:// or https:// URL","messagePattern":"mem0 base_url must be an absolute http:// or https:// URL","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"backend/packages/harness/deerflow/agents/memory/backends/mem0/config.py","lineNumber":114,"sourceCode":"        if config.startup_policy not in _STARTUP_POLICIES:\n            raise ValueError(f\"mem0 startup_policy must be one of {sorted(_STARTUP_POLICIES)}\")\n        if config.read_policy not in _READ_POLICIES:\n            raise ValueError(f\"mem0 failure_policy.read must be one of {sorted(_READ_POLICIES)}\")\n        if config.write_policy not in _WRITE_POLICIES:\n            raise ValueError(f\"mem0 failure_policy.write must be one of {sorted(_WRITE_POLICIES)}\")\n        if not 1 <= config.top_k <= 1000:\n            raise ValueError(\"mem0 top_k must be in [1, 1000]\")\n        if not 0.0 <= config.score_threshold <= 1.0:\n            raise ValueError(\"mem0 score_threshold must be in [0, 1]\")\n        if config.max_injection_chars <= 0:\n            raise ValueError(\"mem0 max_injection_chars must be positive\")\n        if config.timeout_seconds <= 0:\n            raise ValueError(\"mem0 timeout_seconds must be positive\")\n        if not config.api_key_env.strip():\n            raise ValueError(\"mem0 api_key_env must be a non-empty env var name\")\n        parsed_base_url = urlsplit(config.base_url)\n        if parsed_base_url.scheme not in {\"http\", \"https\"} or not parsed_base_url.netloc:\n            raise ValueError(\"mem0 base_url must be an absolute http:// or https:// URL\")\n        if parsed_base_url.scheme == \"http\" and not config.allow_insecure_http:\n            raise ValueError(\"mem0 base_url must use https:// because it carries the API key; set allow_insecure_http: true only for trusted local development\")\n        return config\n\n    def resolve_api_key(self) -> str:\n        \"\"\"Read the API key from the configured environment variable.\"\"\"\n        key = os.environ.get(self.api_key_env, \"\").strip()\n        if not key:\n            raise ValueError(f\"mem0 API key missing: environment variable {self.api_key_env} is unset or empty\")\n        return key\n","sourceCodeStart":96,"sourceCodeEnd":125,"githubUrl":"https://github.com/bytedance/deer-flow/blob/1dd6ba1acb03700589994b0366c5d1c7d05e2eff/backend/packages/harness/deerflow/agents/memory/backends/mem0/config.py#L96-L125","documentation":"Raised by Mem0Config.from_backend_config when base_url, parsed with urlsplit, does not have an http/https scheme plus a network location (host). The URL is used verbatim as the httpx client's base for every mem0 request, so a relative path, a bare host, or a different scheme (ftp, unix socket) cannot work. Note base_url is right-stripped of '/' before parsing.","triggerScenarios":"base_url: mem0.internal:8080 (no scheme), base_url: localhost (no scheme), base_url: \"/api/mem0\" (relative path), or base_url: \"\" after templating.","commonSituations":"Omitting the scheme on internal hostnames (curl tolerates it, this parser does not); templated values where the scheme variable is empty; pasting a path prefix only; trailing-slash or scheme typos like http:/mem0 (single slash yields a bad netloc).","solutions":["Write a fully-absolute URL including scheme and host: base_url: https://api.mem0.ai or base_url: http://mem0.internal:8080","Plain http:// requires allow_insecure_http: true (only for trusted local development)","If templated, make sure both scheme and host variables are populated"],"exampleFix":"# before (config.yaml)\nmemory:\n  backend_config:\n    base_url: mem0.internal:8080   # missing scheme\n\n# after\nmemory:\n  backend_config:\n    base_url: http://mem0.internal:8080\n    allow_insecure_http: true   # required for plain http with this backend","handlingStrategy":"validation","validationCode":"from urllib.parse import urlsplit\n\ndef base_url_ok(backend_config: dict) -> bool:\n    url = str((backend_config or {}).get(\"base_url\", \"https://api.mem0.ai\")).rstrip(\"/\")\n    parts = urlsplit(url)\n    return parts.scheme in {\"http\", \"https\"} and bool(parts.netloc) and (\n        parts.scheme == \"https\" or bool((backend_config or {}).get(\"allow_insecure_http\", False))\n    )","typeGuard":"def is_absolute_http_url(v: object) -> bool:\n    if not isinstance(v, str):\n        return False\n    parts = urlsplit(v.rstrip(\"/\"))\n    return parts.scheme in {\"http\", \"https\"} and bool(parts.netloc)","tryCatchPattern":null,"preventionTips":["Always write base_url with an explicit scheme (https://...); bare hostnames are rejected","Plain http:// additionally requires allow_insecure_http: true — reserve that for local dev","When templating, validate the rendered URL with urlsplit in a config-check CI step"],"tags":["config","mem0","memory","url","validation"],"backgroundTag":null,"analyzedSha":"1dd6ba1acb03700589994b0366c5d1c7d05e2eff","analyzedAt":"2026-08-14T21:20:34.804Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}