hasura/graphql-engine · error · Error
The global ID {encoded_value:} couldn't be decoded due to {d
Error message
The global ID {encoded_value:} couldn't be decoded due to {decoding_error:} What it means
Thrown by the GraphQL IR layer when a relay-style global ID (the base64-encoded 'typename:id' composite) fails to decode. The error carries the raw encoded value and the underlying decoding error message. This typically happens when a value passed as a global ID is malformed, not base64, or doesn't split into the expected node type and ID components.
Source
Thrown at v3/crates/graphql/ir/src/error.rs:40
InternalEngineError::PlanInternalEngineError(engine_error),
)),
plan::InternalError::Developer(developer_error) => {
Error::Internal(InternalError::Developer(
InternalDeveloperError::PlanInternalDeveloperError(developer_error),
))
}
}
}
}
#[allow(clippy::duplicated_attributes)] // suppress spurious warnings from Clippy
#[derive(Error, Debug, Transitive)]
#[transitive(from(json::Error, InternalError))]
#[transitive(from(gql::normalized_ast::Error, InternalError))]
#[transitive(from(InternalEngineError, InternalError))]
#[transitive(from(InternalDeveloperError, InternalError))]
pub enum Error {
#[error("The global ID {encoded_value:} couldn't be decoded due to {decoding_error:}")]
FailureDecodingGlobalId {
encoded_value: String,
decoding_error: String,
},
#[error("Unexpected value: expecting {expected_kind:}, but found: {found:}")]
UnexpectedValue {
expected_kind: &'static str,
found: json::Value,
},
#[error("'{name:}' is not a valid GraphQL name.")]
TypeFieldInvalidGraphQlName { name: String },
#[error("'{alias:} is not a valid alias")]
InvalidAlias { alias: String },
#[error("{value} is not a valid limit value")]View on GitHub (pinned to 724551b9ae)
Solutions
- Regenerate the ID by fetching it from the server (query the node's id field) rather than constructing it client-side
- Verify the ID is the exact base64 string returned by a previous response and hasn't been URL-decoded/trimmed
- If you control the encoder, confirm the 'typename:id' format and base64 variant match the server's decoder
Example fix
# before
query {{ user(id: "12345") {{ id }} }}
# after (use the global ID returned by the server)
query {{ user(id: "VXNlcjoxMjM0NQ==") {{ id }} }} Defensive patterns
Strategy: validation
Validate before calling
function isGlobalId(v: string): boolean {{
try {{
const decoded = atob(v);
return /^[^:]+:.+$/.test(decoded);
}} catch {{ return false; }}
}}
if (!isGlobalId(idArg)) throw new TypeError('Expected a server-issued global ID'); Type guard
function isGlobalId(v: string): v is string {{
try {{ return /^[^:]+:.+$/.test(atob(v)); }} catch {{ return false; }}
}} Try / catch
try {{
const node = await client.request({{ query: NODE_QUERY, variables: {{ id }} }});
}} catch (e: any) {{
if (/global ID.*couldn't be decoded/.test(e.message)) {{ /* re-fetch valid ID or return null */ }}
throw e;
}} Prevention
- Always round-trip IDs from server responses instead of constructing them
- Never store raw DB IDs where the API expects global IDs
- Guard shared IDs with a decode-and-check helper before sending
When it happens
Trigger: Passing a non-global-ID string (e.g. a raw database ID or arbitrary text) to an argument that expects a node ID; passing a global ID encoded with a different scheme or whose base64 payload doesn't contain the expected separator; corrupted ID from client-side manipulation.
Common situations: Clients fabricating IDs or reusing IDs from another environment/encoder; migrating ID formats while stale clients still send old IDs; copy-paste truncation of base64 values.
Related errors
- error from data source: {}
- subscription are not supported over HTTP
- parsing failed: {0}
- validation failed: {0}
- explain error: {0}
AI-assisted analysis of hasura/graphql-engine@724551b9ae (2026-08-28).
Data as JSON: /api/errors/3177c04f17b1e0f0.
Report an issue: GitHub.