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

  1. Inspect the argument presets for the named argument in the role's permission config and remove one of the conflicting definitions
  2. Keep all values for one argument either literal or predicate-based, never mixed
  3. 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

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


AI-assisted analysis of hasura/graphql-engine@724551b9ae (2026-08-28). Data as JSON: /api/errors/daf938e7f785c39a. Report an issue: GitHub.