{"record":{"id":"47d206e05f3a0156","repo":"HKUDS/Vibe-Trading","slug":"edgar-full-text-search-returned-no-hits-block-me","errorCode":null,"errorMessage":"EDGAR full-text search returned no hits block: {message or payload}","messagePattern":"EDGAR full-text search returned no hits block: (.+?)","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"agent/src/tools/institutional_holdings_tool.py","lineNumber":283,"sourceCode":"        params: Query parameters (``q`` / ``forms`` / ``ciks`` / ``entityName`` /\n            ``startdt`` / ``enddt`` / ``from``).\n\n    Returns:\n        ``{\"total\": int, \"total_is_lower_bound\": bool, \"hits\": [source-dicts\n        with an extra \"_id\" key]}``. Elasticsearch stops counting at 10,000 and\n        reports ``relation: \"gte\"``, so a total at that ceiling is a floor and\n        must never be presented as an exact count.\n\n    Raises:\n        RuntimeError: When the response carries no ``hits`` block — full-text\n            search answers HTTP 200 with an error document when it is unhappy.\n        requests.RequestException: On transport failure.\n    \"\"\"\n    payload = _sec_get(_FTS_URL, {\"q\": \"\", **params}).json()\n    hits = payload.get(\"hits\") if isinstance(payload, dict) else None\n    if not isinstance(hits, dict):\n        message = payload.get(\"errorMessage\") if isinstance(payload, dict) else None\n        raise RuntimeError(f\"EDGAR full-text search returned no hits block: {message or payload}\")\n    rows: List[Dict[str, Any]] = []\n    for hit in hits.get(\"hits\") or []:\n        source = hit.get(\"_source\") if isinstance(hit, dict) else None\n        if isinstance(source, dict):\n            rows.append({**source, \"_id\": hit.get(\"_id\")})\n    total = hits.get(\"total\") if isinstance(hits.get(\"total\"), dict) else {}\n    return {\n        \"total\": int(total.get(\"value\") or 0),\n        \"total_is_lower_bound\": total.get(\"relation\") == \"gte\",\n        \"hits\": rows,\n    }\n\n\ndef _positive(value: float, default: float) -> float:\n    \"\"\"Return *value* when it is positive, else *default*.\n\n    The config layer already drops unparseable overrides; this only guards\n    against a syntactically valid but nonsensical zero or negative bound.","sourceCodeStart":265,"sourceCodeEnd":301,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/tools/institutional_holdings_tool.py#L265-L301","documentation":"_fts queries the SEC EDGAR full-text search API and expects an Elasticsearch-style {'hits': {...}} dict. If the payload is not a dict, or the 'hits' key is missing/not a dict (e.g. an error envelope with errorMessage), this RuntimeError is raised with the SEC-provided message or raw payload. It typically reflects upstream API errors, rate limiting, or a changed response schema.","triggerScenarios":"SEC returns 403/429 HTML-error JSON, an {'errorMessage': ...} body, or the FTS endpoint changes shape; also transient SEC outages. Called via _resolve_manager, _list_13f_filings, _ticker_holders, _top_managers.","commonSituations":"Missing/stale SEC User-Agent header causing 403; heavy polling triggering rate limits; schema drift in EDGAR FTS.","solutions":["Verify the request sends a proper SEC-required User-Agent identifying your app","Retry with exponential backoff — SEC rate limits are often transient","Log the payload; if it shows a schema change, update the hits parsing in _fts"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"for attempt in range(3):\n    try:\n        rows = _fts(params)\n        break\n    except RuntimeError as e:\n        if \"no hits block\" in str(e) and attempt < 2:\n            time.sleep(2 ** attempt)\n            continue\n        raise","preventionTips":["Set a descriptive SEC User-Agent header","Cache FTS results to stay under rate limits","Monitor payload shape; alert on errorMessage envelopes"],"tags":["sec-edgar","http","api-contract","rate-limit"],"backgroundTag":"upstream-api-bad-response","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}