{"record":{"id":"a35a693f706e10f5","repo":"nexu-io/open-design","slug":"missing-xiaohongshu-api-base-url","errorCode":null,"errorMessage":"Missing Xiaohongshu API base URL","messagePattern":"Missing Xiaohongshu API base URL","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"design-templates/last30days/scripts/lib/xiaohongshu_api.py","lineNumber":77,"sourceCode":"\ndef _build_note_url(feed_id: str, xsec_token: str) -> str:\n    \"\"\"Build a stable Xiaohongshu note URL.\"\"\"\n    if xsec_token:\n        return f\"https://www.xiaohongshu.com/explore/{feed_id}?xsec_token={xsec_token}\"\n    return f\"https://www.xiaohongshu.com/explore/{feed_id}\"\n\n\ndef search_feeds(\n    topic: str,\n    from_date: str,\n    to_date: str,\n    base_url: str,\n    depth: str = \"default\",\n) -> List[Dict[str, Any]]:\n    \"\"\"Search Xiaohongshu feeds and normalize to web-item shape.\"\"\"\n    base = (base_url or \"\").rstrip(\"/\")\n    if not base:\n        raise ValueError(\"Missing Xiaohongshu API base URL\")\n\n    # Quick login sanity check.\n    login = http.get(f\"{base}/api/v1/login/status\", timeout=8, retries=1)\n    is_logged_in = (\n        login.get(\"data\", {}).get(\"is_logged_in\")\n        if isinstance(login, dict) else False\n    )\n    if not is_logged_in:\n        raise http.HTTPError(\"Xiaohongshu API reachable but not logged in\")\n\n    # API supports filters; use recency-oriented defaults.\n    publish_time = \"一天内\" if depth == \"quick\" else \"一周内\" if depth == \"default\" else \"半年内\"\n    payload = {\n        \"keyword\": topic,\n        \"filters\": {\n            \"sort_by\": \"综合\",\n            \"note_type\": \"不限\",\n            \"publish_time\": publish_time,","sourceCodeStart":59,"sourceCodeEnd":95,"githubUrl":"https://github.com/nexu-io/open-design/blob/5be4028344c2eb4c667c5a97bda8f750c5597ef7/design-templates/last30days/scripts/lib/xiaohongshu_api.py#L59-L95","documentation":"Raised in xiaohongshu_api.search_feeds when the base_url argument is empty after rstrip('/'). Note env.get_xiaohongshu_api_base always returns a default of http://host.docker.internal:18060 when XIAOHONGSHU_API_BASE is unset, so in the normal pipeline path this ValueError only fires if an explicit empty string is passed (or the env default is deliberately overridden to empty).","triggerScenarios":"Calling search_feeds(..., base_url='') or base_url=None directly. Overriding XIAOHONGSHU_API_BASE to an empty string in config. A custom orchestrator that passes env.get_xiaohongshu_api_base result after stripping it to empty.","commonSituations":"Programmatic caller that built base_url from an unset env var without the env default. Test that monkeypatched the base to ''. Docker host unreachable is a DIFFERENT error (HTTPError 'reachable but not logged in'), not this one.","solutions":["Let env.get_xiaohongshu_api_base supply its default; do not pass an explicit empty base_url.","If overriding XIAOHONGSHU_API_BASE, set it to a real URL (e.g. http://localhost:18060).","Validate base_url is non-empty before calling search_feeds."],"exampleFix":"# before\nxiaohongshu_api.search_feeds(topic, frm, to, base_url='')\n\n# after\nfrom lib import env\nxiaohongshu_api.search_feeds(topic, frm, to, env.get_xiaohongshu_api_base(config))","handlingStrategy":"validation","validationCode":"def search_feeds_safe(topic, frm, to, base_url, depth=\"default\"):\n    base = (base_url or \"\").rstrip(\"/\")\n    if not base:\n        raise ValueError(\"Xiaohongshu API base URL is required\")\n    return xiaohongshu_api.search_feeds(topic, frm, to, base, depth=depth)","typeGuard":"def has_base_url(base_url) -> bool:\n    return bool(base_url and base_url.strip())","tryCatchPattern":"null","preventionTips":["Always obtain base_url via env.get_xiaohongshu_api_base(config) so the default applies.","Never override XIAOHONGSHU_API_BASE to an empty string; unset it instead to get the default.","Distinguish this config error from the runtime 'reachable but not logged in' HTTPError."],"tags":["config","validation","xiaohongshu","api-base"],"backgroundTag":null,"analyzedSha":"5be4028344c2eb4c667c5a97bda8f750c5597ef7","analyzedAt":"2026-08-12T12:03:58.812Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}