dagger/dagger · error · TooManyNestedObjectsError

Too many nested objects inside graphql response

Error message

Too many nested objects inside graphql response

What it means

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.

Source

Thrown at sdk/typescript/src/common/graphql/compute_query.ts:211

/**
 * Return a Graphql query result flattened
 * @param response any
 * @returns
 */
export function queryFlatten<T>(response: any): T {
  // Recursion break condition
  // If our response is not an object or an array we assume we reached the value
  if (!(response instanceof Object) || Array.isArray(response)) {
    return response
  }

  const keys = Object.keys(response)

  if (keys.length != 1) {
    // Dagger is currently expecting to only return one value
    // If the response is nested in a way were more than one object is nested inside throw an error
    throw new TooManyNestedObjectsError(
      "Too many nested objects inside graphql response",
      {
        response: response,
      },
    )
  }

  const nestedKey = keys[0]

  return queryFlatten(response[nestedKey])
}

/**
 * Send a GraphQL document to the server
 * return a flatten result
 * @hidden
 */
export async function compute<T>(

View on GitHub (pinned to 82ba2681db)

Solutions

  1. Issue one root field per GraphQL query; split multi-root queries into separate calls
  2. Inspect the raw response to find the unexpected extra root key (log response before compute)
  3. Remove any proxy/middleware that decorates the response with extra top-level fields
  4. Upgrade the SDK/engine if the API legitimately changed its response shape

Example fix

// before (multi-root query)
query { container { id } directory { id } }
// after
query { container { id } }  // separate query for directory
Defensive patterns

Strategy: try-catch

Validate before calling

// Sanity-check that only one root field is requested
const rootFields = query.match(/\{\s*(\w+)/g);
if (rootFields && rootFields.length > 1) {
  throw new Error('GraphQL query must have exactly one root field for Dagger');
}

Type guard

function isSingleKeyResponse(res) {
  return res && typeof res === 'object' && Object.keys(res).length === 1;
}

Try / catch

import { TooManyNestedObjectsError } from '@dagger.io/dagger/errors';
try {
  const result = await computeQuery(client, query)
} catch (e) {
  if (e instanceof TooManyNestedObjectsError) {
    // split the query into single-root-field queries
  }
  throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of dagger/dagger@82ba2681db (2026-09-05). Data as JSON: /api/errors/14196387d0af8e4a. Report an issue: GitHub.