hasura/graphql-engine · error · PermissionError::CommandNotAccessible
no permission to select from command {command_name:}
Error message
no permission to select from command {command_name:} What it means
PermissionError::CommandNotAccessible is raised during permission evaluation when the requesting role has no select permission (or an explicit deny) for the named command, so the query is refused before planning proceeds. It is a permissions failure, distinct from CommandNotFound which means the command doesn't exist at all.
Source
Thrown at v3/crates/plan/src/types.rs:58
Self::Permission(permission_error) => permission_error.visibility(),
Self::Relationship(relationship_error) => relationship_error.visibility(),
Self::OrderBy(order_by_error) => order_by_error.visibility(),
Self::BooleanExpression(boolean_expression_error) => {
boolean_expression_error.visibility()
}
Self::Internal(_) => ErrorVisibility::Internal,
}
}
}
#[derive(Debug, thiserror::Error)]
// errors thrown during permissions evaluation, but not necessary errors due to permisssions
pub enum PermissionError {
#[error("command {command_name:} could not be found")]
CommandNotFound {
command_name: Qualified<CommandName>,
},
#[error("no permission to select from command {command_name:}")]
CommandNotAccessible {
command_name: Qualified<CommandName>,
},
#[error("model {model_name:} could not be found")]
ModelNotFound { model_name: Qualified<ModelName> },
#[error("model {model_name:} has no source")]
ModelHasNoSource { model_name: Qualified<ModelName> },
#[error("no permission to select from model {model_name:}")]
ModelNotAccessible { model_name: Qualified<ModelName> },
#[error("object type {object_type_name:} could not be found")]
ObjectTypeNotFound {
object_type_name: Qualified<CustomTypeName>,
},
#[error("no permission to select from type {object_type_name:}")]
ObjectTypeNotAccessible {
object_type_name: Qualified<CustomTypeName>,View on GitHub (pinned to 724551b9ae)
Solutions
- Add a permission entry for the required role on the command (allow select/execute)
- Verify the request's session role (X-Hasura-Role) matches a role defined in the command's permissions
- If access should be denied, handle this error as an authorization response rather than a bug
- Check for typos in role names in both metadata and JWT claims
Example fix
// before
// command "get_users" has no permissions block
// after
permissions: [ { role: "user", actions: ["select"] } ] // metadata for command get_users Defensive patterns
Strategy: try-catch
Validate before calling
// Before executing, check the role has permission for the command
fn can_select_command(permissions: &[CommandPermission], role: &str, cmd: &str) -> bool {
permissions.iter().any(|p| p.command == cmd && p.role == role && p.can_select)
} Try / catch
Match PermissionError::CommandNotAccessible and convert to an HTTP 403/authorization error for the client; do not retry.
Prevention
- Define permissions for every role that will call each command
- Automate metadata permission provisioning (IaC for Hasura metadata)
- Log the requesting role on authorization failures to speed diagnosis
When it happens
Trigger: Querying a command (custom query/mutation exposed by a data connector) under a role that lacks a permission entry allowing select/execute on it — e.g. as an anonymous user or a role without the command granted.
Common situations: Forgetting to add command permissions for the admin/anon/other roles; role name mismatch between the session/JWT role and metadata role definitions; testing a new command before attaching permissions; env differences where dev metadata has permissions but prod does not.
Related errors
- no permission to select from model {model_name:}
- no permission to select from type {object_type_name:}
- 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/0f9dd235deec4cdc.
Report an issue: GitHub.