hasura/graphql-engine · error · ConditionError
Number for {side}-hand value of comparison operation is outs
Error message
Number for {side}-hand value of comparison operation is outside precision or range of a double-precision float What it means
Thrown by the authorization-rules condition evaluator when one side of a comparison operation (e.g. _eq, _gt, _lte on numbers) holds a number that cannot be represented exactly as an f64 double-precision float. The engine compares numeric values as doubles, so values requiring more precision (e.g. huge integers or high-precision decimals) are rejected rather than silently rounded.
Source
Thrown at v3/crates/auth/authorization-rules/src/condition.rs:25
use crate::ConditionCache;
use metadata_resolve::{
BinaryOperation, Condition, ConditionHash, Conditions, UnaryOperation, ValueExpression,
};
use open_dds::query::ArgumentName;
#[derive(Debug, PartialEq, Eq, thiserror::Error)]
pub enum ConditionError {
#[error("Session variable not found: {name}")]
SessionVariableNotFound { name: SessionVariableName },
#[error("Serde error: {error}")]
SerdeError { error: String },
#[error("Condition {condition_hash} not found")]
ConditionNotFound { condition_hash: ConditionHash },
#[error("Expected array or null for right-hand value of contains operation")]
ExpectedArrayOrNullForContains,
#[error("Expected number for {side}-hand value of comparison operation")]
ExpectedNumberForComparison { side: Side },
#[error(
"Number for {side}-hand value of comparison operation is outside precision or range of a double-precision float"
)]
NumberOutOfRange { side: Side },
#[error(
"Tried to combine a predicate with a literal in argument presets for argument {argument_name}"
)]
CouldNotCombinePredicateAndLiteralArgumentPresets { argument_name: ArgumentName },
}
// evaluate conditions used in permissions
fn evaluate_condition(
condition: &Condition,
session_variables: &SessionVariables,
) -> Result<bool, ConditionError> {
match condition {
Condition::All(conditions) => conditions.iter().try_fold(true, |acc, condition| {
Ok(acc && evaluate_condition(condition, session_variables)?)
}),View on GitHub (pinned to 724551b9ae)
Solutions
- Reduce the compared value's magnitude/precision so it fits exactly in a double (integers within ±2^53)
- Store and compare the value as a string instead of a number if exactness matters
- Move the comparison out of the permission rule into application logic or a computed expression that supports arbitrary precision
Example fix
// before
{ "type": "_eq", "left": { "column": "snowflake_id" }, "right": 9007199254740993 }
// after
{ "type": "_eq", "left": { "column": "snowflake_id_str" }, "right": "9007199254740993" } Defensive patterns
Strategy: validation
Validate before calling
fn fits_f64(n: &serde_json::Number) -> bool {
if let Some(i) = n.as_i64() {
i.abs() <= (2i64.pow(53))
} else {
n.as_f64().map(|f| serde_json::Number::from_f64(f).as_ref() == Some(n)).unwrap_or(false)
}
}
assert!(fits_f64(&right_hand_value)); Type guard
fn isDoubleSafe(n: serde_json::Number) -> bool {
n.as_f64()
.and_then(|f| serde_json::Number::from_f64(f))
.map(|rt| rt == n)
.unwrap_or(false)
} Try / catch
match condition_eval {
Err(ConditionError::NumberOutOfRange { side }) => return_policy_deny_with_reason(side),
r => r,
} Prevention
- Keep numeric literals in permission rules within ±2^53
- Prefer string-typed columns for very large identifiers
- Validate preset values with a round-trip f64 check in config CI
When it happens
Trigger: Defining a permission rule with a comparison operator where the left-hand (session variable/column) or right-hand (literal) value is an integer exceeding 2^53 or a decimal with more precision than an f64 can hold, and the value then fails to round-trip through f64.
Common situations: Using 64-bit or UUID-like numeric IDs, snowflake IDs, or high-precision decimal literals in permission comparison expressions in OpenDD auth configuration.
Related errors
- Session variable not found: {name}
- Serde error: {error}
- Condition {condition_hash} not found
- Expected array or null for right-hand value of contains oper
- Expected number for {side}-hand value of comparison operatio
AI-assisted analysis of hasura/graphql-engine@724551b9ae (2026-08-28).
Data as JSON: /api/errors/8557d8695a5ebfde.
Report an issue: GitHub.