{"record":{"id":"ba1e068873c7c3d9","repo":"HKUDS/Vibe-Trading","slug":"no-base-self-quote-currency-rate-for-day-pa","errorCode":null,"errorMessage":"no {base}/{self.quote_currency} rate for {day}; pass allow_stale=True to reuse the most recent earlier rate instead -- stale reuse is flagged on the translated flow, never applied silently","messagePattern":"no (.+?)/(.+?) rate for (.+?); pass allow_stale=True to reuse the most recent earlier rate instead -- stale reuse is flagged on the translated flow, never applied silently","errorType":"exception","errorClass":"MissingExchangeRateError","httpStatus":null,"severity":"error","filePath":"agent/src/entities/cashflow.py","lineNumber":655,"sourceCode":"\n        Returns:\n            A tuple of the ``FxRate`` used and whether it was stale (its\n            ``date`` is earlier than ``on_date``).\n\n        Raises:\n            MissingExchangeRateError: If there is no exact same-day quote and\n                either ``allow_stale`` is False, or no earlier quote exists\n                (within ``max_staleness_days`` when given).\n        \"\"\"\n        base = normalize_currency(base_currency, field_name=\"base_currency\")\n        day = normalize_date(on_date)\n\n        exact = self.rates.get((base, day))\n        if exact is not None:\n            return exact, False\n\n        if not allow_stale:\n            raise MissingExchangeRateError(\n                f\"no {base}/{self.quote_currency} rate for {day}; pass \"\n                \"allow_stale=True to reuse the most recent earlier rate \"\n                \"instead -- stale reuse is flagged on the translated flow, \"\n                \"never applied silently\"\n            )\n\n        candidates = [\n            entry\n            for (entry_base, entry_date), entry in self.rates.items()\n            if entry_base == base and entry_date <= day\n        ]\n        if max_staleness_days is not None:\n            candidates = [\n                entry\n                for entry in candidates\n                if (day - entry.date).days <= max_staleness_days\n            ]\n        if not candidates:","sourceCodeStart":637,"sourceCodeEnd":673,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/entities/cashflow.py#L637-L673","documentation":"FxRateTable.get_rate raises MissingExchangeRateError when no exact (base, date) quote exists and allow_stale is False. The library never silently substitutes a different day's rate: stale reuse must be opted into and is flagged on the translated flow.","triggerScenarios":"table.get_rate('EUR', date(2024,3,15)) when only a 2024-03-14 EUR quote exists and allow_stale is omitted/False; equivalently translate_cashflows hitting a settlement date with no quote.","commonSituations":"Weekend/holiday settlement dates with weekday-only FX feeds; a table built from month-end rates used on intra-month dates; forgetting to extend the rates file after a new data range.","solutions":["Pass allow_stale=True (or allow_stale_rates=True on translate_cashflows) to reuse the most recent earlier quote, accepting the staleness flag","Add an FxRate for the exact missing (base, date) — e.g. source a daily FX series covering all settlement dates","Broaden max_staleness_days if the default window excludes an otherwise acceptable earlier quote"],"exampleFix":"# before\nrate, stale = table.get_rate('EUR', date(2024,3,16))  # Saturday, no quote\n# after\nrate, stale = table.get_rate('EUR', date(2024,3,16), allow_stale=True)\n# or: table.translate_cashflows(flows, allow_stale_rates=True)","handlingStrategy":"try-catch","validationCode":"needed = {(f.currency, f.date) for f in flows}\nhave = set(table.rates)\nmissing = needed - have - {(c, None) for c in {f.currency for f in flows}}\n# approximate; exact-coverage check requires date-level set comparison","typeGuard":null,"tryCatchPattern":"from agent.src.entities.cashflow import MissingExchangeRateError\ntry:\n    table.translate_cashflows(flows)\nexcept MissingExchangeRateError:\n    translated = table.translate_cashflows(flows, allow_stale_rates=True)","preventionTips":["Source daily FX series covering all settlement dates","Default to allow_stale_rates=True for weekend/holiday dates, and audit the staleness flags","Extend the rates file whenever the flow date range grows"],"tags":["python","fx-rate","missing-data"],"backgroundTag":"missing-fx-rate","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}