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

  1. Regenerate the ID by fetching it from the server (query the node's id field) rather than constructing it client-side
  2. Verify the ID is the exact base64 string returned by a previous response and hasn't been URL-decoded/trimmed
  3. 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

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


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