{"record":{"id":"da293e71c57d50c8","repo":"Hmbown/CodeWhale","slug":"invalid-cost-currency-other-expected-usd-cny","errorCode":null,"errorMessage":"Invalid cost_currency '{other}': expected usd, cny, rmb, or yuan","messagePattern":"Invalid cost_currency '(.+?)': expected usd, cny, rmb, or yuan","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/config_ui.rs","lineNumber":1303,"sourceCode":"    }\n\n    #[allow(dead_code)]\n    fn description(self) -> &'static str {\n        match self {\n            Self::Agent => \"Do the work in this session.\",\n            Self::Plan => \"Design first; implement after you approve.\",\n            Self::Operate => \"Dispatch workers; keep the parent free for steers.\",\n        }\n    }\n}\n\nimpl CostCurrencyValue {\n    fn from_setting(value: &str) -> Result<Self> {\n        match value.trim().to_ascii_lowercase().as_str() {\n            \"usd\" => Ok(Self::Usd),\n            \"cny\" | \"rmb\" | \"yuan\" => Ok(Self::Cny),\n            other => {\n                anyhow::bail!(\"Invalid cost_currency '{other}': expected usd, cny, rmb, or yuan\")\n            }\n        }\n    }\n\n    fn as_setting(self) -> &'static str {\n        match self {\n            Self::Usd => \"usd\",\n            Self::Cny => \"cny\",\n        }\n    }\n}\n\nimpl From<ApprovalMode> for ApprovalModeValue {\n    fn from(value: ApprovalMode) -> Self {\n        match value {\n            ApprovalMode::Auto => Self::Auto,\n            ApprovalMode::Bypass => Self::Bypass,\n            ApprovalMode::Suggest => Self::Suggest,","sourceCodeStart":1285,"sourceCodeEnd":1321,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/0c42157ee52f9d55af2b506d71b46249910f77d3/crates/tui/src/config_ui.rs#L1285-L1321","documentation":"Thrown by CostCurrencyValue::from_setting when the cost_currency setting, after trim and ASCII lowercasing, is not one of usd, cny, rmb, or yuan. cny/rmb/yuan all map to Cny; only these four spellings are accepted and there is no empty-string default, so a blank value also fails.","triggerScenarios":"Setting cost_currency to anything else: \"eur\", \"jpy\", \"us\", or \"\" (empty). Triggered wherever from_setting parses the setting during config load.","commonSituations":"Hand-editing config with an ISO code that was never supported; clearing the value instead of using \"usd\"; scripts writing uppercase with different spacing (\"USD \" is fine after trim, but \"US D\" is not).","solutions":["Set cost_currency to \"usd\", \"cny\", \"rmb\", or \"yuan\" (case-insensitive)","If you need another currency, request it upstream; do not keep an unsupported value in config","Remove typos or trailing punctuation from the value"],"exampleFix":"# before\ncost_currency = \"eur\"\n\n# after\ncost_currency = \"usd\"","handlingStrategy":"validation","validationCode":"fn normalize_cost_currency(value: &str) -> Option<&'static str> {\n    match value.trim().to_ascii_lowercase().as_str() {\n        \"usd\" => Some(\"usd\"),\n        \"cny\" | \"rmb\" | \"yuan\" => Some(\"cny\"),\n        _ => None,\n    }\n}\n\n// before saving:\nlet Some(currency) = normalize_cost_currency(input) else {\n    return Err(anyhow::anyhow!(\"cost_currency must be usd, cny, rmb, or yuan\"));\n};","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use a closed dropdown of the four accepted spellings instead of free-form input","Normalize at write time (trim + lowercase) so reads never see \"USD \" variants","Treat empty as invalid: pick an explicit default currency in the UI"],"tags":["config","currency","rust","tui","invalid-value"],"backgroundTag":"unsupported-currency-code","analyzedSha":"0c42157ee52f9d55af2b506d71b46249910f77d3","analyzedAt":"2026-08-20T21:50:45.477Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}