hasura/graphql-engine · error · ModelPermissionError

model source is required for model '{model_name:}' to resolv

Error message

model source is required for model '{model_name:}' to resolve predicate

What it means

ModelSourceRequiredForPredicate: a model permission uses a row-level filter predicate (e.g. a select `filter`), but the model has no source configured. Predicates compile against the model's data source, so a source-less model cannot support filter permissions.

Source

Thrown at v3/crates/metadata-resolve/src/stages/model_permissions/error.rs:30

#[derive(Debug, thiserror::Error)]
#[error("Error in model permission for model '{model_name}'{}: {error}",
        match role { Some(role) => format!(" for role '{role}'"), None => String::new()}
)]
pub struct NamedModelPermissionError {
    pub model_name: Qualified<ModelName>,
    pub role: Option<Spanned<Role>>,
    pub error: ModelPermissionError,
}

#[derive(Debug, thiserror::Error)]
pub enum ModelPermissionError {
    #[error("preset argument '{argument_name}' is defined more than once")]
    DuplicateModelArgumentPreset {
        argument_name: Spanned<ArgumentName>,
    },

    #[error("model source is required for model '{model_name:}' to resolve predicate")]
    ModelSourceRequiredForPredicate {
        model_name: Spanned<Qualified<ModelName>>,
    },

    #[error("preset argument '{argument_name}' value has a type error: {type_error}")]
    ModelArgumentValuePresetTypeError {
        argument_name: Spanned<ArgumentName>,
        value_path: JSONPath,
        type_error: typecheck::TypecheckError,
    },

    #[error(
        "a preset argument '{argument_name}' has been set for the model '{model_name}' but no such argument exists for this model"
    )]
    ModelArgumentPresetArgumentNotFound {
        model_name: Spanned<Qualified<ModelName>>,
        argument_name: Spanned<ArgumentName>,
    },

View on GitHub (pinned to 724551b9ae)

Solutions

  1. Add a `source` to the model so the predicate can be resolved against the data connector
  2. Or remove the `filter` from the permission if row filtering is not intended for this model
  3. If a source exists, verify the model references it correctly (source configuration is on the model, not the type)

Example fix

# before
kind: Model
version: v1
definition:
  name: users
  # no source
permissions:
  - role: user
    select:
      filter: { id: { eq: X-Hasura-User-Id } }

# after
kind: Model
version: v1
definition:
  name: users
  source:
    dataConnectorName: pg
    collection: users
permissions:
  - role: user
    select:
      filter: { id: { eq: X-Hasura-User-Id } }
Defensive patterns

Strategy: validation

Validate before calling

for model in models:
    perms = model.get('permissions', [])
    has_filter = any('filter' in list(p.values())[0] for p in perms if p.values())
    assert not has_filter or 'source' in model['definition'], \
        f"model {model['definition']['name']} has filter permission but no source"

Prevention

When it happens

Trigger: Adding a `filter` to a model permission in OpenDD metadata while the model has no `source` block (only a `command` or type binding without source configuration).

Common situations: Converting a command-based model to have permissions, removing a model source but leaving filters behind, or writing permissions for a model that was never bound to a data connector.

Related errors


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