{"record":{"id":"9060d951a38c337a","repo":"transact-rs/sqlx","slug":"reading-a-money-value-in-text-format-is-not-supp","errorCode":null,"errorMessage":"Reading a `MONEY` value in text format is not supported.","messagePattern":"Reading a `MONEY` value in text format is not supported\\.","errorType":"exception","errorClass":"io::Error (InvalidData)","httpStatus":null,"severity":"error","filePath":"sqlx-postgres/src/types/money.rs","lineNumber":184,"sourceCode":"\nimpl Encode<'_, Postgres> for PgMoney {\n    fn encode_by_ref(&self, buf: &mut PgArgumentBuffer) -> Result<IsNull, BoxDynError> {\n        buf.extend(&self.0.to_be_bytes());\n\n        Ok(IsNull::No)\n    }\n}\n\nimpl Decode<'_, Postgres> for PgMoney {\n    fn decode(value: PgValueRef<'_>) -> Result<Self, BoxDynError> {\n        match value.format() {\n            PgValueFormat::Binary => {\n                let cents = BigEndian::read_i64(value.as_bytes()?);\n\n                Ok(PgMoney(cents))\n            }\n            PgValueFormat::Text => {\n                let error = io::Error::new(\n                    io::ErrorKind::InvalidData,\n                    \"Reading a `MONEY` value in text format is not supported.\",\n                );\n\n                Err(Box::new(error))\n            }\n        }\n    }\n}\n\nimpl Add<PgMoney> for PgMoney {\n    type Output = PgMoney;\n\n    /// Adds two monetary values.\n    ///\n    /// # Panics\n    /// Panics if overflowing the `i64::MAX`.\n    fn add(self, rhs: PgMoney) -> Self::Output {","sourceCodeStart":166,"sourceCodeEnd":202,"githubUrl":"https://github.com/transact-rs/sqlx/blob/03af8bcc5711a1935580a54bea249c219a0c217d/sqlx-postgres/src/types/money.rs#L166-L202","documentation":"Postgres MONEY values in text format include locale-dependent formatting such as currency symbols and thousands separators, which sqlx cannot safely parse. Therefore PgMoney's Decode impl only supports the binary wire format and deliberately rejects text format with this error. The library chooses to fail explicitly rather than guess at parsing localized text.","triggerScenarios":"Fetching a MONEY column as PgMoney when the query executes over the text protocol — e.g. a plain (unprepared) query via `sqlx::query` with simple_query, or a connection/driver configuration forcing text format.","commonSituations":"Using `simple_query` for quick reads of MONEY columns; running through tools or pools that force text format; selecting `money::text` and still binding to PgMoney; migrations/replication tools that emit text rows.","solutions":["Use a regular prepared query (`sqlx::query(...).fetch_...`) so the binary format is used","Cast the column in SQL to a numeric type and decode to i64/f64/BigDecimal: `SELECT amount::numeric FROM t`","Change the column type to NUMERIC/BIGINT (cents) which both formats support","If you must read text, fetch as String and strip currency symbols/separators manually before constructing PgMoney(cents)"],"exampleFix":"// before\nlet row = sqlx::query(\"SELECT amount FROM payments\").fetch_one(&db).await?; // simple_query/text path\nlet money: PgMoney = row.get(\"amount\");\n// after: use prepared query or cast\nlet money: PgMoney = sqlx::query_scalar(\"SELECT amount FROM payments\").fetch_one(&db).await?;\n// or\nlet cents: i64 = sqlx::query_scalar(\"SELECT amount::numeric::bigint FROM payments\").fetch_one(&db).await?;","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"// decode MONEY defensively, falling back to a numeric cast\nlet money: PgMoney = match sqlx::query_scalar(\"SELECT amount FROM payments\").fetch_one(&db).await {\n    Ok(m) => m,\n    Err(e) if e.to_string().contains(\"text format is not supported\") => {\n        let cents: i64 = sqlx::query_scalar(\"SELECT amount::numeric::bigint FROM payments\").fetch_one(&db).await?;\n        PgMoney(cents)\n    }\n    Err(e) => return Err(e.into()),\n};","preventionTips":["Never read MONEY columns via simple_query or other text-format paths","Prefer NUMERIC/BIGINT (cents) column types over Postgres MONEY","Cast in SQL (::numeric) when interop with text-based tooling is required"],"tags":["postgres","money","decode","text-format"],"backgroundTag":"postgres-type-decode-failed","analyzedSha":"03af8bcc5711a1935580a54bea249c219a0c217d","analyzedAt":"2026-09-03T15:01:28.752Z","contentChangedAt":"2026-09-03T15:01:28.752Z","schemaVersion":2},"datasetVersion":"2026-09-10T17:17:09.494Z"}