Skip to content

3.2.7: TypeError "Redefinition of reserved type 'ID'" when constructing GraphQLScalarType('ID') (works on 3.2.6) #248

@kamilqui

Description

@kamilqui

Summary

Upgrading graphql-core from 3.2.6 to 3.2.7 changes behavior when constructing a GraphQLScalarType named "ID".

In 3.2.6 this succeeds, but in 3.2.7 it raises:
TypeError: Redefinition of reserved type 'ID'.

Environment

  • graphql-core: 3.2.6 vs 3.2.7
  • Python: reproduced on Python 3.13.x and 3.14.2
  • OS: reproduced on Fedora Linux, Ubuntu (Azure App Service), and macOS

Reproduction code

import sys
import graphql
from graphql import build_schema, GraphQLScalarType

SDL = "type Query { ping: String }"

def main():
    print("python:", sys.version.split()[0])
    print("graphql-core:", graphql.__version__)

    schema = build_schema(SDL)

    custom_id = GraphQLScalarType(
        name="ID",
        serialize=str,
        parse_value=lambda v: v,
        parse_literal=lambda node, _vars=None: None,
    )

    schema.type_map["ID"] = custom_id
    print("Replaced ID scalar in schema.type_map successfully")

if __name__ == "__main__":
    main()

Output with graphql-core 3.2.6

python: 3.14.2
graphql-core: 3.2.6
Replaced ID scalar in schema.type_map successfully

Output with graphql-core 3.2.7

python: 3.14.2
graphql-core: 3.2.7
Traceback (most recent call last):
  ...
  File ".../graphql/type/definition.py", line 236, in __new__
    raise TypeError(f"Redefinition of reserved type {name!r}")
TypeError: Redefinition of reserved type 'ID'

Impact

In APIs backed by Postgres, it’s common for IDs to be stored as BIGINT. GraphQL ID inputs typically arrive as strings, and with asyncpg that can result in bound parameters typed as VARCHAR. When those values are used in filters against BIGINT columns, Postgres can raise errors like:

operator does not exist: bigint = character varying

(e.g., WHERE user_id IN ($1::VARCHAR, $2::VARCHAR)).

Some wrappers/frameworks address this by overriding/parsing ID values (numeric strings -> int) at the GraphQL scalar layer to avoid bigint/varchar comparison issues. The 3.2.6 → 3.2.7 behavior change here breaks that pattern.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions