{"record":{"id":"4a37019270019859","repo":"OpenBB-finance/OpenBB","slug":"invalid-port-code-item-must-be-a-valid-port-id","errorCode":null,"errorMessage":"Invalid port_code: {item}. Must be a valid port ID or name.Available options: {port_id_choices}.","messagePattern":"Invalid port_code: (.+?)\\. Must be a valid port ID or name\\.Available options: (.+?)\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"openbb_platform/providers/imf/openbb_imf/models/port_volume.py","lineNumber":150,"sourceCode":"                    v_.replace(\" - \", \"_\").replace(\"-\", \"_\").lower().replace(\" \", \"_\")\n                    for v_ in port_id_map.values()\n                ]\n                idx = values_snake.index(item_lower)\n                new_item = port_id_map[idx]\n                new_values.append(new_item)\n            # Accept first part of port name (before dash)\n            elif item_lower in [\n                v_.split(\" - \")[0].lower().replace(\" \", \"_\")\n                for v_ in port_id_map.values()\n            ]:\n                first_parts = [\n                    v_.split(\" - \")[0].lower().replace(\" \", \"_\")\n                    for v_ in port_id_map.values()\n                ]\n                idx = first_parts.index(item_lower)\n                new_values.append(list(port_id_map.keys())[idx])\n            else:\n                raise ValueError(\n                    f\"Invalid port_code: {item}. Must be a valid port ID or name.Available options: {port_id_choices}.\"\n                )\n\n        if not new_values:\n            raise ValueError(\"No valid port_code provided.\")\n\n        return \",\".join(new_values)\n\n    @model_validator(mode=\"before\")\n    @classmethod\n    def validate_model(cls, values):\n        \"\"\"Validate the model before instantiation.\"\"\"\n        if values.get(\"start_date\") is not None and values[\"start_date\"] < dateType(\n            2019, 1, 1\n        ):\n            raise OpenBBError(\n                ValueError(\n                    f\"Minimum start_date is 2019-01-01. Got {values['start_date']} instead.\"","sourceCodeStart":132,"sourceCodeEnd":168,"githubUrl":"https://github.com/OpenBB-finance/OpenBB/blob/3e071fcc2cd9f891cac6040ae60296dba76dab46/openbb_platform/providers/imf/openbb_imf/models/port_volume.py#L132-L168","documentation":"Raised in the port_code validator when an item matches neither a port id (map key), a port name, a country name, nor the first part of a port name before ' - '. The message dumps the entire `port_id_choices` list, which is large. Note the missing space in 'name.Available' is a message formatting artifact. A sibling 'No valid port_code provided.' error exists when all items are filtered out.","triggerScenarios":"Passing a port code that is not in the PortWatch ports database (e.g. wrong UN/LOCODE or LMIS id), a misspelled port name, or a name whose 'before dash' part differs from the entry. Matching is on lowercased, space-to-underscore forms, so unusual punctuation or full names containing ' - ' can fail.","commonSituations":"Guessing port ids instead of looking them up via maritime port_info; using a different id scheme (UN/LOCODE vs PortWatch id); trailing whitespace or casing from user input; port names that changed in the database.","solutions":["Look up the exact id/name via the port_info endpoint (or the printed choices) and pass that verbatim.","For names with ' - ' suffixes, try just the part before the dash (e.g. 'new_york').","Trim and normalize whitespace; matching is case-insensitive but exact on characters otherwise.","If the port genuinely is missing from PortWatch, no parameter change will help — choose a nearby covered port."],"exampleFix":"# before\nport_volume(port_code='NYC')\n\n# after\nport_volume(port_code='usnyc')  # exact PortWatch id from port_info","handlingStrategy":"validation","validationCode":"# Resolve against the same sources the validator uses\ninfo = await obb.economy.imf.port_info()\nvalid_ids = {p.port_id for p in info.results}  # or get_port_id_choices()\nvalid_names = {p.name.lower().replace(' ', '_') for p in info.results}\nitem = item.strip().lower().replace(' ', '_')\nif item not in valid_ids and item not in valid_names and item.split(' - ')[0] not in valid_names:\n    raise ValueError(f'unknown port: {item}')","typeGuard":"def is_valid_port_code(item: str, port_id_map: dict) -> bool:\n    i = item.strip().lower().replace(' ', '_')\n    return (i in port_id_map\n            or i in {v.lower().replace(' ', '_') for v in port_id_map.values()}\n            or i in {v.split(' - ')[0].lower().replace(' ', '_') for v in port_id_map.values()})","tryCatchPattern":null,"preventionTips":["Look up ids via port_info once and cache the mapping","Normalize input (strip, lowercase, underscore spaces) before validating","Do not invent ids from other coding schemes (UN/LOCODE etc.)"],"tags":["imf","portwatch","validation","port-code","query-params"],"backgroundTag":null,"analyzedSha":"3e071fcc2cd9f891cac6040ae60296dba76dab46","analyzedAt":"2026-08-14T23:40:48.960Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}