hasura/graphql-engine · error · ConditionError
Tried to combine a predicate with a literal in argument pres
Error message
Tried to combine a predicate with a literal in argument presets for argument {argument_name} What it means
Thrown when building argument presets for a role's permission: the code tried to combine a predicate with a literal value for the same argument. An argument preset must be either a fixed literal or a predicate expression, not both; the merge of two preset definitions produced this conflict.
Source
Thrown at v3/crates/auth/authorization-rules/src/condition.rs:29
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)?)
}),
Condition::Any(conditions) => conditions.iter().try_fold(false, |acc, condition| {
Ok(acc || evaluate_condition(condition, session_variables)?)
}),
Condition::Not(condition) => {View on GitHub (pinned to 724551b9ae)
Solutions
- Inspect the argument presets for the named argument in the role's permission config and remove one of the conflicting definitions
- Keep all values for one argument either literal or predicate-based, never mixed
- After editing, re-run config validation/build to confirm the merge succeeds
Example fix
// before
argumentPresets:
- argument: user_id
value: 42
- argument: user_id
predicate: { column: id }
// after
argumentPresets:
- argument: user_id
predicate: { column: id } Defensive patterns
Strategy: validation
Validate before calling
use std::collections::HashSet;
let mut seen = HashSet::new();
for preset in &argument_presets {
if !seen.insert(preset.argument_name.clone()) {
return Err(format!("duplicate preset for argument {}", preset.argument_name));
}
} Type guard
fn presetsAreConsistent(ps: &[Preset]) -> bool {
ps.iter().all(|p| matches!(p, Preset::Literal(_) | Preset::Predicate(_)))
&& !hasDuplicateArguments(ps)
} Prevention
- Define each argument preset exactly once per role
- Never mix literal and predicate presets for the same argument
- Add CI schema checks that reject duplicate argument names in presets
When it happens
Trigger: A role's argument presets define the same argument_name twice — once as a literal and once as a predicate expression (e.g. via combining presets across multiple permission definitions) — and the engine attempts to merge them.
Common situations: Overlapping permission presets on the same argument from multiple role definitions or an upgraded OpenDD config where presets were consolidated onto one argument.
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/daf938e7f785c39a.
Report an issue: GitHub.