payloadcms / payloadcms/payload
GraphQL queries fail on Cloudflare Workers with "Unexpected input type" — caused by createComplexityRule (graphql-query-complexity)
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 44.8k
- Forks
- 4.2k
- Avg merge
- 2d 21h
- Merged PRs (30d)
- 53
Description
Describe the Bug
Every GraphQL query/mutation fails on Cloudflare Workers with Unexpected input type: Int (and Unexpected input type: mutationUserInput! for mutations). The same setup works fine on Node.
Reproduced with the official with-cloudflare-d1 template (Payload 3.82.1) running on vinext (Cloudflare Workers target, wrangler dev local workerd). The template README notes GraphQL "is not currently guaranteed" on Workers (previously linked to workerd#5175, which is closed and unrelated) — but this issue has a precise root cause worth fixing.
Repro
Standard GraphQL query against the template:
curl -X POST http://localhost:8787/api/graphql \
-H 'content-type: application/json' \
-d '{"query":"{ Users(limit: 1) { docs { id email } } }"}'
Response (Workers/workerd):
[{"message":"Unexpected input type: Int"}]
Mutation fails the same way: Unexpected input type: mutationUserInput!.
Root cause (bisected)
The error comes from graphql's astFromValue/coerceInputValue invariant. Bisection on the @payloadcms/next GraphQL route handler (routes/graphql/handler.js):
configToSchemaoutput is correct (Query.Users args =limit: Int,where: User_where, …)- Executing the query directly via
graphql.executeworks (reaches access control) graphql-http'screateHandlerworks without extra validation rules- Adding
validationRules(payload'screateComplexityRulefrom the vendoredgraphql-query-complexity) makes it fail — this is the exact combination the real endpoint uses - Node validation:
validate(schema, query, specifiedRules.concat([complexityRule]))→ no errors (works fine) - Same code in workerd →
Unexpected input type: Int
So createComplexityRule (from @payloadcms/graphql's vendored graphql-query-complexity) misbehaves under workerd.
Expected behavior
GraphQL queries (including limit/where args) validate and execute on Cloudflare Workers, same as Node.
Environment
- Payload 3.82.1, @payloadcms/next 3.82.1, @payloadcms/graphql 3.82.1
- wrangler 4.116.0 / workerd (local dev), vinext 1.0.0-beta.2, Vite 8.2.1
Impact
GraphQL API is entirely unusable on Workers (both queries and mutations). REST works fine. Full reproduction project with 21-check API coverage script is available on request.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in the @payloadcms/next GraphQL route handler at routes/graphql/handler.js and trace how the vendored graphql-query-complexity createComplexityRule is passed as a validation rule. Reproduce the failure with the provided curl request under workerd, then compare validation with and without the complexity rule. Done means queries and mutations validate and execute on Cloudflare Workers without the Unexpected input type errors while Node behavior remains unchanged.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- graphql, typescript
- Domain
- api, backend, cloud
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100