{"record":{"id":"f6135514aaf32582","repo":"OpenBB-finance/OpenBB","slug":"failed-to-download-category-e","errorCode":null,"errorMessage":"Failed to download {category} -> {e}","messagePattern":"Failed to download (.+?) -> (.+?)","errorType":"exception","errorClass":"OpenBBError","httpStatus":null,"severity":"error","filePath":"openbb_platform/providers/bls/openbb_bls/utils/helpers.py","lineNumber":419,"sourceCode":"    \"\"\"\n    # pylint: disable=import-outside-toplevel\n    import json  # noqa\n    from importlib.resources import files\n    from pathlib import Path\n    from openbb_core.app.model.abstract.error import OpenBBError\n    from openbb_bls.utils.constants import SURVEY_CATEGORY_NAMES\n    from numpy import nan\n    from pandas import DataFrame\n\n    if category not in SURVEY_CATEGORY_NAMES:\n        raise OpenBBError(\n            f\"Category '{category}' not found. Choose from {list(SURVEY_CATEGORY_NAMES)}\"\n        )\n\n    try:\n        ids, codes = await download_category_series_ids(category)\n    except Exception as e:  # pylint: disable=broad-except\n        raise OpenBBError(f\"Failed to download {category} -> {e}\") from e\n\n    assets_path = Path(str(files(\"openbb_bls\").joinpath(\"assets\")))\n\n    # Save the code map to a JSON file.\n    if codes:\n        with open(assets_path.joinpath(f\"{category}_codes.json\"), \"w\") as f:\n            json.dump(codes, f, indent=4)\n\n    # Save the series IDs to a CSV file.\n    if ids:\n        df = DataFrame(ids)\n        df = df.replace({nan: None, \"nan\": None, \"''\": None}).dropna(how=\"all\", axis=1)\n        df.to_csv(\n            assets_path.joinpath(f\"{category}_series.xz\"), index=False, compression=\"xz\"\n        )\n","sourceCodeStart":401,"sourceCodeEnd":435,"githubUrl":"https://github.com/OpenBB-finance/OpenBB/blob/3e071fcc2cd9f891cac6040ae60296dba76dab46/openbb_platform/providers/bls/openbb_bls/utils/helpers.py#L401-L435","documentation":"Raised by the BLS update_survey_files maintenance helper when download_category_series_ids throws for the given category; the original exception is chained (`from e`). The message wraps the underlying failure - which can be a network error, a parsing error on the BLS FTP/HTTP asset, or the EmptyDataError from a bad category map lookup. The root cause is in the chained exception.","triggerScenarios":"BLS survey download endpoints unreachable (offline, firewall, DNS), a survey asset whose layout changed so parsing fails, or the nested EmptyDataError from an unsupported category inside the map.","commonSituations":"Running asset regeneration on CI without network access; BLS changing their FTP file format; transient outages of bls.gov during bulk regeneration runs.","solutions":["Inspect the chained exception (`raise ... from e` preserves it) to identify the true cause","Verify network access to the BLS download endpoints and retry after transient failures","If parsing failed, check whether BLS changed the asset format and adjust get_survey_asset","Confirm the category passes SURVEY_CATEGORY_NAMES and SURVEY_CATEGORY_MAP checks first"],"exampleFix":"# before\nawait update_survey_files('employment')  # opaque wrapper error\n\n# after\ntry:\n    await update_survey_files('employment')\nexcept OpenBBError as e:\n    print('root cause:', e.__cause__)  # inspect chained exception","handlingStrategy":"retry","validationCode":"import socket\nsocket.setdefaulttimeout(30)  # BLS asset downloads can hang/slow","typeGuard":null,"tryCatchPattern":"try:\n    await update_survey_files(cat)\nexcept OpenBBError as e:\n    cause = e.__cause__  # real failure: network, parse, or category guard\n    if is_transient(cause):\n        await asyncio.sleep(10); await update_survey_files(cat)","preventionTips":["Always inspect __cause__ - the wrapper hides the real error","Run asset regeneration on a machine with reliable access to bls.gov","Validate the category against both constants before starting a long run"],"tags":["bls","maintenance","network","wrapped-exception"],"backgroundTag":null,"analyzedSha":"3e071fcc2cd9f891cac6040ae60296dba76dab46","analyzedAt":"2026-08-14T23:40:48.960Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}