Skip to content

fix(ui): bypass GraphQL for createTask, call Queue API directly (fixes #8171)#8260

Open
nitishagar wants to merge 1 commit intotaskcluster:mainfrom
nitishagar:fix/8171-graphql-payload-limit
Open

fix(ui): bypass GraphQL for createTask, call Queue API directly (fixes #8171)#8260
nitishagar wants to merge 1 commit intotaskcluster:mainfrom
nitishagar:fix/8171-graphql-payload-limit

Conversation

@nitishagar
Copy link
Contributor

@nitishagar nitishagar commented Feb 7, 2026

Summary

  • The UI's createTask calls (loaner, retrigger, submitTaskAction, CreateTask page) now call the Queue REST API directly via @taskcluster/client-web instead of routing through GraphQL
  • This fixes 413 errors when creating tasks with payloads larger than 100KB (the default bodyParser.json limit) — up to the Queue API's 10MB limit
  • Also fixes a latent bug where authorizedScopes passed via GraphQL options were silently dropped by the resolver; the Queue client now receives them correctly via getClient({ authorizedScopes: ... })
  • Reverts the server-side body-size limit increases from the previous approach (no changes to createApp.js vs main)
  • Deletes the now-unused createTask.graphql mutation file

Approach

Per architect review by @lotas in #8171: skipping the GraphQL layer for task creation avoids widening the Apollo attack surface (increased body limits have historically been a source of security issues in Apollo).

The UI already uses @taskcluster/client-web for other endpoints (e.g. WorkerManager.removeWorker). Task creation follows the same getClient() pattern.

Test plan

  • cd ui && yarn test — all 52 suites / 137 tests pass (including new submitTaskAction.test.js)
  • cd ui && yarn lint — no errors
  • cd services/web-server && yarn testvalidation_test.js passes with original 413 + PayloadTooLargeError assertions
  • Manually verify task creation with a large payload (>100KB) succeeds in the UI

GitHub Bug/Issue: Fixes #8171

@nitishagar nitishagar requested a review from a team as a code owner February 7, 2026 14:54
@nitishagar nitishagar requested review from lotas, matt-boris and petemoore and removed request for a team February 7, 2026 14:54
@nitishagar nitishagar force-pushed the fix/8171-graphql-payload-limit branch from 73443a3 to 6a3c10f Compare February 8, 2026 07:06
@nitishagar nitishagar force-pushed the fix/8171-graphql-payload-limit branch 2 times, most recently from 699ee32 to 6246159 Compare February 17, 2026 06:26
@nitishagar
Copy link
Contributor Author

@lotas Updated based on the feedback. Please take a look when you get a chance.

cors(corsOptions),
credentials(),
bodyParserGraphql.graphql({
limit: '1mb',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this might no longer be applied because we limit bodyParser at 10mb now

const client = helper.getHttpClient({ suppressErrors: true });
// Send a payload exceeding the 10mb body-parser limit.
// Uses got directly to avoid gql parsing overhead for large payloads.
const response = await got.post(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you know what was the issue with gql? and why we want to avoid this? If you keep original code and just change the value what is happening then?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The got switch was to avoid gql parsing a >10MB string client-side, but that's only needed if we're testing the body parser limit directly. Since we're keeping the original 100k-repeat test (~300KB — well within gql's comfort zone), I've reverted back to using gql + helper client. No issues.

@lotas
Copy link
Contributor

lotas commented Feb 17, 2026

@lotas Updated based on the feedback. Please take a look when you get a chance.

thanks, I have left two comments, I think we need to align limits and I'm not sure why you used got instead of client?

await client.query({
query: gql`
query {
${' a '.repeat(100000)}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I just realized that test was testing something completely different -

maxTokens: 100000,

max tokens is limited to 100000 here, so this test shouldn't be changed

{
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
query: `query { ${'a'.repeat(11 * 1024 * 1024)} }`,
Copy link
Contributor

@lotas lotas Feb 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please note that original test contained spaces around ' a ' for a reason - that test was testing 'maxTokens'

@nitishagar nitishagar force-pushed the fix/8171-graphql-payload-limit branch from 6246159 to c81f421 Compare February 24, 2026 05:58
@nagarwal-godaddy
Copy link

Thank you for the review @lotas! I've addressed the feedback.

@lotas
Copy link
Contributor

lotas commented Feb 25, 2026

Sorry for the delay, I would check this soon, need to make sure that we don't open up some other kind of problems with such increase of max size in graphql, since it was a source of frequent denial-of-service kind of attacks

@lotas
Copy link
Contributor

lotas commented Mar 4, 2026

@nitishagar we have discussed this a bit and came to conclusion that we'd rather use API directly than change graphql body size limits: #8171 (comment)

If you feel comfortable working on this, let me know, otherwise I'll close this PR.
Thank you again for the help so far

@nitishagar nitishagar changed the title fix(web-server): increase GraphQL body size limit to 10mb (fixes #8171) fix(ui): bypass GraphQL for createTask, call Queue API directly (fixes #8171) Mar 13, 2026
@nitishagar nitishagar force-pushed the fix/8171-graphql-payload-limit branch from c81f421 to a2ae12e Compare March 13, 2026 07:02
Task creation in the UI now calls the Queue REST API directly
using @taskcluster/client-web instead of routing through the
GraphQL web-server. This fixes 413 errors when creating tasks
with payloads larger than 100KB (the default bodyParser.json
limit), without requiring any server-side limit increases.

Also fixes a latent bug where authorizedScopes passed via
GraphQL options were silently dropped by the resolver; the
Queue client now receives them correctly.

Closes taskcluster#8171
@nitishagar nitishagar force-pushed the fix/8171-graphql-payload-limit branch from a2ae12e to 25c072b Compare March 13, 2026 08:20
form,
action,
apolloClient,
user,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please check

const taskId = await submitTaskAction({
task,
taskActions,
form,
action,
apolloClient,
});

TaskGroup is still calling this without a user context

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Creating a task via UI fails (payload too large) while python Queue API succeeds with same payload

3 participants