{"record":{"id":"ec4610fdade27f84","repo":"HKUDS/Vibe-Trading","slug":"field-name-entries-must-be-non-empty-strings","errorCode":null,"errorMessage":"{field_name} entries must be non-empty strings","messagePattern":"(.+?) entries must be non-empty strings","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"agent/src/tools/cashflow_analytics_tool.py","lineNumber":447,"sourceCode":"\n    Args:\n        raw: Value supplied for ``external_kinds`` or ``internal_kinds``.\n        field_name: Name used in the error message.\n\n    Returns:\n        The list of labels, or ``None`` to keep the module default.\n\n    Raises:\n        ValueError: If the value is not an array of non-empty strings.\n    \"\"\"\n    if raw is None:\n        return None\n    if not isinstance(raw, list) or not raw:\n        raise ValueError(f\"{field_name} must be a non-empty array of kind labels\")\n    labels: list[str] = []\n    for item in raw:\n        if not isinstance(item, str) or not item.strip():\n            raise ValueError(f\"{field_name} entries must be non-empty strings\")\n        labels.append(item)\n    return labels\n\n\ndef _rounded(value: float) -> float:\n    \"\"\"Round a finite scalar for stable, compact JSON.\n\n    Args:\n        value: Number to round.\n\n    Returns:\n        The value rounded to :data:`_ROUNDING` decimal places.\n    \"\"\"\n    return round(float(value), _ROUNDING)\n\n\ndef _rounded_or_none(value: float | None) -> float | None:\n    \"\"\"Round a scalar that may be deliberately absent.","sourceCodeStart":429,"sourceCodeEnd":465,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/tools/cashflow_analytics_tool.py#L429-L465","documentation":"Each entry inside an include_kinds/exclude_kinds list must be a non-empty string. The coercion rejects non-string items (ints, None, nested lists) and strings that are empty or whitespace-only, since kind labels are matched against flow records verbatim.","triggerScenarios":"Passing include_kinds=[\"dividend\", \"\"] or [\"dividend\", 0] or [None]; a whitespace-only label like \"  \" also triggers it.","commonSituations":"Parsing labels from CSV/JSON where blank cells become empty strings; mixing codes and labels; LLM-generated filter arrays containing nulls.","solutions":["Strip and drop falsy/non-string items from the list before calling","Fix the data source so kind labels are always non-empty strings"],"exampleFix":"# before\nexecute(flows=flows, include_kinds=[\"coupon\", \"\", None])\n# after\nkinds = [k for k in raw_kinds if isinstance(k, str) and k.strip()]\nexecute(flows=flows, include_kinds=kinds or None)","handlingStrategy":"validation","validationCode":"def clean_kinds(raw):\n    if raw is None:\n        return None\n    cleaned = [k.strip() for k in raw if isinstance(k, str) and k.strip()]\n    return cleaned or None","typeGuard":"def all_nonempty_strings(seq) -> bool:\n    return isinstance(seq, list) and all(isinstance(k, str) and k.strip() for k in seq)","tryCatchPattern":"try:\n    execute(flows=flows, include_kinds=kinds)\nexcept ValueError as exc:\n    if \"entries must be non-empty strings\" in str(exc):\n        kinds = [k for k in kinds if isinstance(k, str) and k.strip()]\n        execute(flows=flows, include_kinds=kinds or None)\n    else:\n        raise","preventionTips":["Sanitize user/CSV-derived labels: strip whitespace and drop blanks before building the filter","Reject null items when deserializing JSON configs","Keep kind labels canonicalized to a fixed vocabulary"],"tags":["validation","string","cashflow","python"],"backgroundTag":"invalid-list-item-type","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}