{"record":{"id":"14196387d0af8e4a","repo":"dagger/dagger","slug":"too-many-nested-objects-inside-graphql-response","errorCode":null,"errorMessage":"Too many nested objects inside graphql response","messagePattern":"Too many nested objects inside graphql response","errorType":"exception","errorClass":"TooManyNestedObjectsError","httpStatus":null,"severity":"error","filePath":"sdk/typescript/src/common/graphql/compute_query.ts","lineNumber":211,"sourceCode":"\n/**\n * Return a Graphql query result flattened\n * @param response any\n * @returns\n */\nexport function queryFlatten<T>(response: any): T {\n  // Recursion break condition\n  // If our response is not an object or an array we assume we reached the value\n  if (!(response instanceof Object) || Array.isArray(response)) {\n    return response\n  }\n\n  const keys = Object.keys(response)\n\n  if (keys.length != 1) {\n    // Dagger is currently expecting to only return one value\n    // If the response is nested in a way were more than one object is nested inside throw an error\n    throw new TooManyNestedObjectsError(\n      \"Too many nested objects inside graphql response\",\n      {\n        response: response,\n      },\n    )\n  }\n\n  const nestedKey = keys[0]\n\n  return queryFlatten(response[nestedKey])\n}\n\n/**\n * Send a GraphQL document to the server\n * return a flatten result\n * @hidden\n */\nexport async function compute<T>(","sourceCodeStart":193,"sourceCodeEnd":229,"githubUrl":"https://github.com/dagger/dagger/blob/82ba2681dbe30d3547a1dc50ea495900ab5b6047/sdk/typescript/src/common/graphql/compute_query.ts#L193-L229","documentation":"queryFlatten unwraps the single top-level key of a GraphQL response, because Dagger's protocol expects exactly one root field per query. If the response object has zero or multiple keys, the SDK cannot know which value to unwrap and throws TooManyNestedObjectsError.","triggerScenarios":"A GraphQL response whose root object contains more than one key (or none), e.g. a hand-written multi-root query or a proxy/gateway returning extra envelope fields alongside the data root.","commonSituations":"Custom queries built against the Dagger API that request two root fields at once; middleware (mock servers, caching gateways) injecting additional top-level properties into the response.","solutions":["Issue one root field per GraphQL query; split multi-root queries into separate calls","Inspect the raw response to find the unexpected extra root key (log response before compute)","Remove any proxy/middleware that decorates the response with extra top-level fields","Upgrade the SDK/engine if the API legitimately changed its response shape"],"exampleFix":"// before (multi-root query)\nquery { container { id } directory { id } }\n// after\nquery { container { id } }  // separate query for directory","handlingStrategy":"try-catch","validationCode":"// Sanity-check that only one root field is requested\nconst rootFields = query.match(/\\{\\s*(\\w+)/g);\nif (rootFields && rootFields.length > 1) {\n  throw new Error('GraphQL query must have exactly one root field for Dagger');\n}","typeGuard":"function isSingleKeyResponse(res) {\n  return res && typeof res === 'object' && Object.keys(res).length === 1;\n}","tryCatchPattern":"import { TooManyNestedObjectsError } from '@dagger.io/dagger/errors';\ntry {\n  const result = await computeQuery(client, query)\n} catch (e) {\n  if (e instanceof TooManyNestedObjectsError) {\n    // split the query into single-root-field queries\n  }\n  throw e;\n}","preventionTips":["Never issue multi-root-field GraphQL queries against the Dagger API","Log the raw response when wrapping the API through proxies","Remove middleware that adds extra top-level keys to responses","Keep queries generated by the SDK rather than hand-written"],"tags":["typescript","graphql","response-parsing","sdk-internals"],"backgroundTag":"graphql-response-shape-error","analyzedSha":"82ba2681dbe30d3547a1dc50ea495900ab5b6047","analyzedAt":"2026-09-05T07:21:37.930Z","contentChangedAt":"2026-09-05T07:21:37.930Z","schemaVersion":2},"datasetVersion":"2026-09-12T12:17:11.808Z"}