-
-
Notifications
You must be signed in to change notification settings - Fork 144
Description
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.