{"record":{"id":"7cfc8101e1ac19ac","repo":"transact-rs/sqlx","slug":"varbit-data-contains-other-characters-than-1-or-0","errorCode":null,"errorMessage":"VARBIT data contains other characters than 1 or 0.","messagePattern":"VARBIT data contains other characters than 1 or 0\\.","errorType":"exception","errorClass":"io::Error (InvalidData)","httpStatus":null,"severity":"error","filePath":"sqlx-postgres/src/types/bit_vec.rs","lineNumber":87,"sourceCode":"                // Chop off zeroes from the back. We get bits in bytes, so if\n                // our bitvec is not in full bytes, extra zeroes are added to\n                // the end.\n                while bitvec.len() > len {\n                    bitvec.pop();\n                }\n\n                Ok(bitvec)\n            }\n            PgValueFormat::Text => {\n                let s = value.as_str()?;\n                let mut bit_vec = BitVec::with_capacity(s.len());\n\n                for c in s.chars() {\n                    match c {\n                        '0' => bit_vec.push(false),\n                        '1' => bit_vec.push(true),\n                        _ => {\n                            Err(io::Error::new(\n                                io::ErrorKind::InvalidData,\n                                \"VARBIT data contains other characters than 1 or 0.\",\n                            ))?;\n                        }\n                    }\n                }\n\n                Ok(bit_vec)\n            }\n        }\n    }\n}\n","sourceCodeStart":69,"sourceCodeEnd":100,"githubUrl":"https://github.com/transact-rs/sqlx/blob/03af8bcc5711a1935580a54bea249c219a0c217d/sqlx-postgres/src/types/bit_vec.rs#L69-L100","documentation":"sqlx's BitVec decoding for Postgres parses the VARBIT/BIT text representation as a string of '0' and '1' characters. When the server sends text-format data containing any other character, the decoder cannot map it to bits and fails with this io::ErrorKind::InvalidData error. It indicates corrupted or unexpected wire data rather than a caller mistake in most cases.","triggerScenarios":"Decoding a Postgres BIT or VARBIT column into sqlx's BitVec when the value arrives in PgValueFormat::Text and contains characters other than 0/1, e.g. binary-format-like escapes, a prefixed 'B'/'X' literal, or whitespace.","commonSituations":"Querying a bit column through a proxy or driver setting that forces text protocol; manually cast values like `bit 'X1F'` or hex/bit strings stored with prefixes; reading a column whose declared type differs from stored data after a migration.","solutions":["Use the binary protocol so BIT/VARBIT values are sent as raw bytes: keep default prepared statements, or cast explicitly to a text-safe type in SQL","Check the actual column data with `SELECT col::text` for stray characters (prefixes, spaces) and clean the data","Decode to String or Vec<u8> instead of BitVec if the column may hold non-canonical bit text, and parse it yourself","Verify the column type is actually BIT/VARBIT, not TEXT that merely looks like bits"],"exampleFix":"// before: decoding a possibly hex-prefixed column directly into BitVec\nlet bits: bitvec::vec::BitVec = sqlx::query_scalar(\"SELECT flags FROM t\").fetch_one(&pool).await?;\n// after: normalize in SQL or decode as text and parse\nlet raw: String = sqlx::query_scalar(\"SELECT flags::text FROM t\").fetch_one(&pool).await?;\nlet cleaned: String = raw.chars().filter(|c| *c == '0' || *c == '1').collect();","handlingStrategy":"validation","validationCode":"// validate text-form bit data before decoding into BitVec\nfn is_valid_bit_text(s: &str) -> bool {\n    !s.is_empty() && s.chars().all(|c| c == '0' || c == '1')\n}\nlet raw: String = sqlx::query_scalar(\"SELECT flags::text FROM t\").fetch_one(&pool).await?;\nassert!(is_valid_bit_text(&raw), \"unexpected BIT text: {raw:?}\");","typeGuard":"fn as_bit_text(v: &str) -> Option<Vec<bool>> {\n    v.chars().map(|c| match c { '0' => Some(false), '1' => Some(true), _ => None }).collect()\n}","tryCatchPattern":"match result {\n    Ok(bits) => handle(bits),\n    Err(e) if e.to_string().contains(\"VARBIT data contains other characters\") => {\n        // fall back to parsing raw text yourself\n        let raw: String = sqlx::query_scalar(\"SELECT flags::text FROM t\").fetch_one(&pool).await?;\n        handle(parse_bits_manually(&raw)?);\n    }\n    Err(e) => return Err(e.into()),\n}","preventionTips":["Prefer prepared queries so BIT columns arrive in binary format","Keep BIT/VARBIT column data canonical (only 0/1, no prefixes or whitespace)","Cast to ::text and inspect data when migrating legacy columns"],"tags":["postgres","decode","bitvec","invalid-data"],"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"}