{"record":{"id":"8be85732213eab1f","repo":"hasura/graphql-engine","slug":"error-in-pre-parse-plugin-0","errorCode":null,"errorMessage":"error in pre-parse plugin: {0}","messagePattern":"error in pre-parse plugin: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"v3/crates/graphql/graphql-ws/src/protocol/subscribe.rs","lineNumber":23,"sourceCode":"use ::pre_response_plugin::execute::PreResponsePluginResponse;\nuse axum::http;\nuse blake2::{Blake2b, Digest};\nuse engine_types::ExposeInternalErrors;\nuse graphql_frontend::{ExecuteQueryResult, RootFieldResult, process_response};\nuse graphql_ir::RequestPlan;\nuse hasura_authn_core::Session;\nuse indexmap::IndexMap;\nuse nonempty::NonEmpty;\nuse pre_parse_plugin::execute as pre_parse_plugin;\nuse pre_response_plugin::execute as pre_response_plugin;\n\n#[derive(thiserror::Error, Debug)]\nenum Error {\n    #[error(\"graphql-ws protocol is not initialized\")]\n    NotInitialized,\n    #[error(\"poller with operation_id {} already exists\", operation_id.0)]\n    PollerAlreadyExists { operation_id: OperationId },\n    #[error(\"error in pre-parse plugin: {0}\")]\n    PreParsePlugin(#[from] pre_parse_plugin::Error),\n}\n\nimpl tracing_util::TraceableError for Error {\n    fn visibility(&self) -> tracing_util::ErrorVisibility {\n        tracing_util::ErrorVisibility::User\n    }\n}\n\n/// Handles the subscription message from the client.\n/// It either starts a new poller or sends a close message if the poller with given operation_id already exists.\npub async fn handle_subscribe<M: WebSocketMetrics>(\n    client_address: std::net::SocketAddr,\n    connection: ws::Connection<M>,\n    operation_id: OperationId,\n    payload: lang_graphql::http::RawRequest,\n    runtime_flags: metadata_resolve::flags::RuntimeFlags,\n) {","sourceCodeStart":5,"sourceCodeEnd":41,"githubUrl":"https://github.com/hasura/graphql-engine/blob/724551b9ae87845594ef0408cff0e50eb6c90dc5/v3/crates/graphql/graphql-ws/src/protocol/subscribe.rs#L5-L41","documentation":"A pre-parse plugin executed as part of subscription processing returned an error before the GraphQL query could be parsed. The graphql-ws pipeline runs registered pre-parse plugins (e.g. query allow-listing, validation) prior to parsing, and any plugin failure aborts with this error.","triggerScenarios":"Registering a pre-parse plugin (query allow-list, persisted-query resolution, size limits) and receiving a subscribe message that the plugin rejects — e.g. a query not on the allow-list or exceeding a configured limit.","commonSituations":"Deploying a new query not yet added to the allow-list; persisted-query hash unknown to the server; plugin misconfiguration after a version upgrade changes plugin APIs.","solutions":["Identify which pre-parse plugin rejected the request from server logs (the inner pre_parse_plugin::Error has details)","If using an allow-list, add the new query/hash to the plugin's configuration","Verify plugin configuration (persisted query manifests, size limits) is deployed alongside the code","Test queries against the plugin configuration in CI before deploying"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"catch (e) { if (String(e).includes('pre-parse plugin')) { surface 'query not allowed' to caller; log inner error; } }","preventionTips":["Keep query allow-lists/persisted-query manifests in CI with the client queries","Test new queries against plugin config before release","Log the inner plugin error for triage"],"tags":["graphql-ws","plugins","graphql-validation","subscriptions"],"backgroundTag":"graphql-plugin-rejected-request","analyzedSha":"724551b9ae87845594ef0408cff0e50eb6c90dc5","analyzedAt":"2026-08-28T07:32:55.105Z","schemaVersion":2},"datasetVersion":"2026-08-28T11:17:15.048Z"}