{"record":{"id":"a01f2759956eba28","repo":"HKUDS/Vibe-Trading","slug":"carry-rate-must-be-in-0-1-got-carry-rate-r","errorCode":null,"errorMessage":"carry_rate must be in [0, 1), got {carry_rate!r}","messagePattern":"carry_rate must be in \\[0, 1\\), got (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"agent/src/quantlib/fundmath.py","lineNumber":1175,"sourceCode":"            exceed ``carry_rate``, or the tier could never complete.\n\n    Returns:\n        A :class:`WaterfallResult` whose tiers sum exactly to ``distributable``.\n\n    Raises:\n        ValueError: If any amount is negative, if ``carry_rate`` is outside\n            ``[0, 1)``, if ``catch_up_rate`` is outside ``[0, 1]``, or if a\n            non-zero ``catch_up_rate`` does not exceed ``carry_rate``.\n    \"\"\"\n    for label, value in (\n        (\"distributable\", distributable),\n        (\"contributed_capital\", contributed_capital),\n        (\"preferred_amount\", preferred_amount),\n    ):\n        if value < 0.0:\n            raise ValueError(f\"{label} must be non-negative, got {value!r}\")\n    if not 0.0 <= carry_rate < 1.0:\n        raise ValueError(f\"carry_rate must be in [0, 1), got {carry_rate!r}\")\n    if not 0.0 <= catch_up_rate <= 1.0:\n        raise ValueError(f\"catch_up_rate must be in [0, 1], got {catch_up_rate!r}\")\n    if catch_up_rate > 0.0 and catch_up_rate <= carry_rate:\n        raise ValueError(\n            f\"catch_up_rate={catch_up_rate!r} must exceed carry_rate=\"\n            f\"{carry_rate!r}, otherwise the catch-up tier can never complete. \"\n            \"Pass catch_up_rate=0.0 for a fund with no catch-up.\"\n        )\n\n    remaining = float(distributable)\n\n    return_of_capital = min(remaining, float(contributed_capital))\n    remaining -= return_of_capital\n\n    preferred_paid = min(remaining, float(preferred_amount))\n    remaining -= preferred_paid\n\n    if catch_up_rate > 0.0 and carry_rate > 0.0:","sourceCodeStart":1157,"sourceCodeEnd":1193,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/quantlib/fundmath.py#L1157-L1193","documentation":"Carry (performance fee) rate must lie in [0, 1): 0 means no carry and values >= 1 (100%) are meaningless, and exactly 1 makes the GP take everything with no LP residual defined.","triggerScenarios":"Calling waterfall_split(carry_rate=1.0) or 1.2, or passing a percentage (20) instead of a fraction (0.20).","commonSituations":"Percent-vs-fraction confusion from config files storing '20' for 20%; UI inputs in percent passed through unconverted.","solutions":["Pass the rate as a fraction: 0.20 for 20%","Divide percent values by 100 at the config boundary"],"exampleFix":"# before\nwaterfall_split(..., carry_rate=20)\n\n# after\nwaterfall_split(..., carry_rate=20 / 100)","handlingStrategy":"validation","validationCode":"assert 0.0 <= carry_rate < 1.0, carry_rate","typeGuard":"def is_fraction(x: float) -> bool:\n    return isinstance(x, (int, float)) and 0.0 <= x < 1.0","tryCatchPattern":null,"preventionTips":["Convert percentages to fractions at the config/UI boundary","Name config fields carry_rate_pct to make units explicit"],"tags":["fund-math","waterfall","carry-rate","percent-vs-fraction"],"backgroundTag":"invalid-argument-range","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}