OpenBB-finance/OpenBB · error · OpenBBError
port_code must be a string or a list of strings.
Error message
port_code must be a string or a list of strings.
What it means
Field validator on `port_code` in the port_volume query params: after normalizing a string (single value or comma-split) to a list, the value must be a list of strings. Non-string items (ints, floats, None mixed in) or a non-list/non-string input type (dict, int) raise this before any port-id resolution happens.
Source
Thrown at openbb_platform/providers/imf/openbb_imf/models/port_volume.py:83
description="Port code to filter results by a specific port."
+ " This parameter is ignored if `country` parameter is provided."
+ " To get a list of available ports, use `obb.economy.shipping.port_info()`.",
)
country: PortCountries | None = Field(
default=None,
description="Country to focus on. Enter as a 3-letter ISO country code."
+ " This parameter is overridden by `port_code` if both are provided.",
)
@field_validator("port_code")
@classmethod
def validate_port_code(cls, v):
"""Validate port_code."""
if isinstance(v, str):
v = [v] if "," not in v else v.split(",")
if not isinstance(v, list) or not all(isinstance(item, str) for item in v):
raise OpenBBError("port_code must be a string or a list of strings.")
port_id_choices = get_port_id_choices()
port_id_map = {
choice["value"].lower(): choice["label"] for choice in port_id_choices
}
# Create country name to ISO code mapping
country_name_to_iso = {}
for iso_code, country_name in PORT_COUNTRIES.items():
country_name_to_iso[country_name.lower()] = iso_code
country_name_to_iso[country_name.lower().replace(" ", "_")] = iso_code
new_values: list = []
for item in v:
if item == "all":
return "all"
# Try direct ISO country code lookup firstView on GitHub (pinned to 3e071fcc2c)
Solutions
- Pass port codes as strings: `port_code='port12345'` or `port_code=['port12345','usnyc']`.
- Map numeric inputs with str() before building the query.
- Validate the shape (list[str]) at your API boundary before calling.
Example fix
# before port_volume(port_code=[37972, 'usnyc']) # after port_volume(port_code=['37972', 'usnyc'])
Defensive patterns
Strategy: type-guard
Validate before calling
if isinstance(port_code, str):
port_code = [p.strip() for p in port_code.split(',')] if ',' in port_code else [port_code]
if not isinstance(port_code, list) or not all(isinstance(p, str) for p in port_code):
port_code = [str(p) for p in port_code] # or reject at your boundary Type guard
def is_port_code_input(v) -> bool:
if isinstance(v, str):
return True
return isinstance(v, list) and all(isinstance(x, str) for x in v) Prevention
- Quote numeric ids in JSON configs
- Coerce DB/pandas numeric port ids with str() before calling
When it happens
Trigger: Passing `port_code=12345` (numeric port id), `port_code=[12345, 'usnyc']` with numeric elements, or a dict/other object. A plain string or list of strings passes this stage and moves on to name/id matching.
Common situations: Upstream data pipelines supplying port ids as integers from a database; JSON configs where numbers are not quoted; pandas cells yielding numpy ints.
Related errors
- Invalid chokepoint value: {v} -> Expected a string or a list
- Invalid port_code: {item}. Must be a valid port ID or name.A
- Invalid chokepoint name: {chokepoint} -> Expected one of {li
- Invalid chokepoint name: {v} -> Expected one of {list(CHOKEP
- Invalid chokepoint name: {chokepoint}. Expected one of {list
AI-assisted analysis of OpenBB-finance/OpenBB@3e071fcc2c (2026-08-14).
Data as JSON: /api/errors/5dd61c9cc94669e6.
Report an issue: GitHub.