{"record":{"id":"5b0c9b14de48b378","repo":"HKUDS/Vibe-Trading","slug":"instrumentids-batch-limit-is-50","errorCode":null,"errorMessage":"instrumentIds batch limit is 50","messagePattern":"instrumentIds batch limit is 50","errorType":"validation","errorClass":"EtoroAPIError","httpStatus":null,"severity":"warning","filePath":"agent/src/trading/connectors/etoro/instruments.py","lineNumber":346,"sourceCode":"        raise EtoroAPIError(f\"instrument not found for symbol {token!r}\")\n\n    candidates.sort(key=lambda pair: (-pair[0], pair[1]))\n    return candidates[0][1]\n\n\ndef get_instrument_metadata(\n    instrument_ids: list[int] | tuple[int, ...],\n    config: EtoroConfig | None = None,\n) -> dict[str, Any]:\n    \"\"\"Fetch display metadata for one or more instrument ids (batch ≤ 50).\"\"\"\n    from src.trading.connectors.etoro.client import load_config\n\n    cfg = config or load_config()\n    ids = [int(i) for i in instrument_ids if int(i) not in _INVALID_INSTRUMENT_IDS and int(i) > 0]\n    if not ids:\n        raise EtoroAPIError(\"at least one valid instrument_id is required\")\n    if len(ids) > 50:\n        raise EtoroAPIError(\"instrumentIds batch limit is 50\")\n\n    payload = make_client(cfg).request(\n        \"GET\",\n        MARKET_DATA_INSTRUMENTS_PATH,\n        params={\"instrumentIds\": \",\".join(str(i) for i in ids)},\n        allow_retry=True,\n    )\n    items = _extract_metadata_items(payload)\n    instruments = [_normalize_metadata_row(item) for item in items if isinstance(item, dict)]\n    return {\"status\": \"ok\", **_base_payload(cfg), \"instruments\": instruments}\n\n\ndef _canonical_ticker(token: str) -> str:\n    upper = token.strip().upper()\n    return _SYMBOL_ALIASES.get(upper, upper)\n\n\ndef _looks_like_ticker(token: str) -> bool:","sourceCodeStart":328,"sourceCodeEnd":364,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/trading/connectors/etoro/instruments.py#L328-L364","documentation":"Raised by get_instrument_metadata when more than 50 valid instrument ids are passed; the eToro instrumentIds endpoint caps batches at 50.","triggerScenarios":"get_instrument_metadata(list_of_75_ids); enriching a portfolio with more than 50 distinct positions in one call.","commonSituations":"Large portfolios, bulk enrichment jobs, forgetting to chunk batch requests.","solutions":["Chunk ids into batches of ≤ 50 and merge results","Add a helper that splits lists before calling"],"exampleFix":"# before\nget_instrument_metadata(all_ids)\n# after\nmeta = {}\nfor i in range(0, len(all_ids), 50):\n    for row in get_instrument_metadata(all_ids[i:i+50]):\n        meta[row['instrumentId']] = row","handlingStrategy":"validation","validationCode":"assert 0 < len(ids) <= 50, 'chunk ids into batches of 50'","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always chunk id lists to the documented batch limit","Centralize batching in a helper so limits are enforced in one place"],"tags":["etoro","batch-limit","pagination"],"backgroundTag":"batch-size-limit-exceeded","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}