hasura/graphql-engine · error · BuildRequestError

Failed to convert session variable '{variable_name}': {error

Error message

Failed to convert session variable '{variable_name}': {error}

What it means

One specific session variable could not be converted (typically serialized or coerced) while building the pre-NDC-request plugin call. The variable name is included along with the serde error, so you can pinpoint exactly which claim/value is malformed. This is narrower than SessionConversionError: a single variable's value does not fit its target type.

Source

Thrown at v3/crates/plugins/pre-ndc-request-plugin/src/execute.rs:54

}

#[derive(Debug, thiserror::Error)]
pub enum BuildRequestError {
    #[error("Invalid header name {header_name}: {error}")]
    InvalidHeaderName {
        header_name: String,
        #[source]
        error: InvalidHeaderName,
    },
    #[error("Invalid header value for header {header_name}: {error}")]
    InvalidHeaderValue {
        header_name: HeaderName,
        #[source]
        error: InvalidHeaderValue,
    },
    #[error("Failed to convert session: {0}")]
    SessionConversionError(String),
    #[error("Failed to convert session variable '{variable_name}': {error}")]
    SessionVariableConversionError {
        variable_name: SessionVariableName,
        error: serde_json::Error,
    },
    #[error("Serialization error: {0}")]
    SerializationError(#[from] serde_json::Error),
}

impl TraceableError for Error {
    fn visibility(&self) -> ErrorVisibility {
        match self {
            Error::BuildRequestError(_, _) => ErrorVisibility::Internal,
            Error::PluginUserError { .. }
            | Error::ReqwestError(_)
            | Error::PluginRequestParseError(_)
            | Error::ErrorWhileMakingHTTPRequestToTheHook(_, _)
            | Error::UnexpectedStatusCode(_)
            | Error::PluginInternalError { .. } => ErrorVisibility::User,

View on GitHub (pinned to 724551b9ae)

Solutions

  1. Check the named variable's actual value in your JWT/session and its expected type in plugin config
  2. Fix the claim shape on the IdP side or update the plugin config to match the new shape
  3. Remove the variable from forwarding if the plugin no longer needs it
  4. Re-deploy engine and plugin together after schema changes
Defensive patterns

Strategy: validation

Validate before calling

// verify claim type before enabling forwarding
assert!(matches!(claims.get("roles"), Some(serde_json::Value::Array(_))));

Try / catch

if let Err(Error::SessionVariableConversionError { variable_name, .. }) = res {
    tracing::warn!(variable_name, "session variable type mismatch");
}

Prevention

When it happens

Trigger: A session variable named in plugin config exists in the session but its JSON value cannot serialize/deserialize into the type the plugin wire format requires, e.g. an object where a string is expected.

Common situations: IdP changes a claim from string to array/object (e.g. 'roles' becoming a list); forwarding a nested object into a slot the plugin expects as a scalar; stale plugin config referencing renamed claims.

Related errors


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