{"record":{"id":"477e054012f9b5f2","repo":"hasura/graphql-engine","slug":"user-error-from-plugin-plugin-name","errorCode":null,"errorMessage":"User error from plugin {plugin_name}","messagePattern":"User error from plugin (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"v3/crates/plugins/pre-ndc-request-plugin/src/execute.rs","lineNumber":31,"sourceCode":"\n#[derive(Debug, thiserror::Error)]\npub enum Error {\n    #[error(\"Error while making the HTTP request to the pre-parse plugin {0} - {1}\")]\n    ErrorWhileMakingHTTPRequestToTheHook(String, reqwest::Error),\n    #[error(\"Error while building the request for the pre-parse plugin {0} - {1}\")]\n    BuildRequestError(String, #[source] BuildRequestError),\n    #[error(\"Reqwest error: {0}\")]\n    ReqwestError(reqwest::Error),\n    #[error(\"Unexpected status code: {0}\")]\n    UnexpectedStatusCode(u16),\n    #[error(\"Error parsing the request: {0}\")]\n    PluginRequestParseError(serde_json::error::Error),\n    #[error(\"Internal error from plugin {plugin_name}\")]\n    PluginInternalError {\n        plugin_name: String,\n        error: serde_json::Value,\n    },\n    #[error(\"User error from plugin {plugin_name}\")]\n    PluginUserError {\n        plugin_name: String,\n        error: serde_json::Value,\n    },\n}\n\n#[derive(Debug, thiserror::Error)]\npub enum BuildRequestError {\n    #[error(\"Invalid header name {header_name}: {error}\")]\n    InvalidHeaderName {\n        header_name: String,\n        #[source]\n        error: InvalidHeaderName,\n    },\n    #[error(\"Invalid header value for header {header_name}: {error}\")]\n    InvalidHeaderValue {\n        header_name: HeaderName,\n        #[source]","sourceCodeStart":13,"sourceCodeEnd":49,"githubUrl":"https://github.com/hasura/graphql-engine/blob/724551b9ae87845594ef0408cff0e50eb6c90dc5/v3/crates/plugins/pre-ndc-request-plugin/src/execute.rs#L13-L49","documentation":"The pre-NDC-request plugin rejected the incoming request as invalid from the user's perspective — the payload failed the plugin's own validation rules. The engine surfaces the plugin name plus the plugin's JSON error detail so the client can be told what was wrong. Unlike PluginInternalError, this is a 4xx-style expected failure caused by the request itself.","triggerScenarios":"The plugin hook responds with a user-error body (HTTP 400-ish) and the executor maps it to Error::PluginUserError { plugin_name, error }.","commonSituations":"A request validation plugin rejecting queries with missing headers, forbidden arguments, or auth claims that fail policy checks; role/permission enforcement hooks denying access.","solutions":["Read the error JSON — it states which part of the request the plugin rejected","Fix the client request to satisfy the plugin's validation rule (header, argument, role, etc.)","If the rejection is unexpected, check that the plugin's validation config matches the intended policy","Disable or narrow the plugin rule temporarily in dev to confirm it is the source"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"match result {\n    Err(Error::PluginUserError { plugin_name, error }) => {\n        // map to a 4xx for the client with the plugin's detail\n    }\n    other => other,\n}","preventionTips":["Document the plugin's validation rules for API consumers","Validate requests client-side against the same rules where possible"],"tags":["rust","plugin","validation","http","ndc"],"backgroundTag":"request-validation-rejected","analyzedSha":"724551b9ae87845594ef0408cff0e50eb6c90dc5","analyzedAt":"2026-08-28T07:32:55.105Z","schemaVersion":2},"datasetVersion":"2026-08-28T11:17:15.048Z"}