SeaQL/sea-orm · error
Failed to get json
Error message
Failed to get json
What it means
ProxyRow decodes Postgres JSON/JSONB columns into serde_json::Value and .expect("Failed to get json") panics on sqlx decode failure. Since the target is Option<serde_json::Value>, NULL is handled; the panic means the value's wire type isn't json/jsonb as sqlx sees it, or the value contains something serde_json cannot represent (e.g. NaN/Infinity produced by non-standard serializers).
Source
Thrown at src/driver/sqlx_postgres.rs:656
}
#[cfg(feature = "postgres-array")]
"OID[]" => Value::Array(
sea_query::ArrayType::BigInt,
row.try_get::<Option<Vec<i64>>, _>(c.ordinal())
.expect("Failed to get oid array")
.map(|vals| {
Box::new(
vals.into_iter()
.map(|val| Value::BigInt(Some(val)))
.collect(),
)
}),
),
#[cfg(feature = "with-json")]
"JSON" | "JSONB" => Value::Json(
row.try_get::<Option<serde_json::Value>, _>(c.ordinal())
.expect("Failed to get json")
.map(Box::new),
),
#[cfg(all(
feature = "with-json",
any(feature = "json-array", feature = "postgres-array")
))]
"JSON[]" | "JSONB[]" => Value::Array(
sea_query::ArrayType::Json,
row.try_get::<Option<Vec<serde_json::Value>>, _>(c.ordinal())
.expect("Failed to get json array")
.map(|vals| {
Box::new(
vals.into_iter()
.map(|val| Value::Json(Some(Box::new(val))))
.collect(),
)
}),
),View on GitHub (pinned to e29bcd1b41)
Solutions
- Check the column's real type (udt_name should be json or _/jsonb) and fix the schema with ALTER TABLE ... ALTER COLUMN ... TYPE jsonb USING col::jsonb.
- Cast in the query: SELECT my_col::jsonb AS my_col.
- Ensure the with-json feature (and compatible serde_json version) is enabled on both sea-orm and the sqlx dependency.
- In driver code, replace .expect with error propagation (DbErr::TryIntoError) to surface which ordinal failed.
Example fix
// before
.expect("Failed to get json")
// after
.map_err(|e| DbErr::TryIntoError { value_type: "json".into(), source: e.into() })? Defensive patterns
Strategy: validation
Validate before calling
let udt: (String,) = sqlx::query_as(
"SELECT udt_name FROM information_schema.columns WHERE table_name=$1 AND column_name=$2",
)
.bind("my_table").bind("payload").fetch_one(&pool).await?;
assert!(matches!(udt.0.as_str(), "json" | "jsonb"), "not a json column: {}", udt.0); Type guard
fn is_json_type(udt_name: &str) -> bool { matches!(udt_name, "json" | "jsonb") } Prevention
- Store JSON in real jsonb columns, never text pretending to be json
- Keep the with-json feature and a serde_json version matching sqlx
- Validate data written by other clients is valid JSON (jsonb enforces this)
- Avoid domains over json/jsonb for proxy-read tables
When it happens
Trigger: Selecting a column named "JSON"/"JSONB" by type when the server actually returns a different wire format (e.g. a domain over jsonb in an older Postgres wire type, or a text column that the driver misclassifies), or with the with-json feature enabled while the value exceeds sqlx's decoding limits.
Common situations: Columns created via an ORM migration that ended up as text instead of jsonb; reading a view whose output type differs from the base table; Postgres extensions returning json-compatible types under a different OID.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- Failed to get uuid
- Failed to get uuid array
- Failed to get oid
- Failed to get oid array
- Failed to get json array
AI-assisted analysis of SeaQL/sea-orm@e29bcd1b41 (2026-09-10).
Data as JSON: /api/errors/ef993d9ea5b70ab4.
Report an issue: GitHub.