Admin GraphQL API returns HTTP 500 instead of proper GraphQL error when response payload is large

When using the nodes query to fetch refund details (including transactions, refundLineItems, refundShippingLines, orderAdjustments) for multiple orders at once, the API returns a raw HTTP 500:

{"errors": "Internal Server Error"}

The query works fine for each order individually and for smaller batches. The 500 only occurs when the combined response size would be large. This is consistent and reproducible, not intermittent.

Query to reproduce:

query getOrdersByIds($ids: [ID!]!) {
  nodes(ids: $ids) {
    ... on Order {
      id
      refunds(first: 200) {
        id
        createdAt
        note
        updatedAt
        totalRefundedSet {
          shopMoney { amount, currencyCode }
          presentmentMoney { amount, currencyCode }
        }
        transactions(first: 50) {
          nodes {
            id
            authorizationCode
            amountSet {
              presentmentMoney { amount, currencyCode }
              shopMoney { amount, currencyCode }
            }
            gateway
            kind
            receiptJson
            status
            test
            createdAt
            paymentId
            processedAt
          }
        }
        refundShippingLines(first: 100) {
          nodes {
            id
            subtotalAmountSet { shopMoney { amount, currencyCode } }
            taxAmountSet { shopMoney { amount, currencyCode } }
          }
        }
        refundLineItems(first: 100) {
          nodes {
            id
            location { id }
            quantity
            restockType
            subtotalSet {
              shopMoney { amount, currencyCode }
              presentmentMoney { amount, currencyCode }
            }
            totalTaxSet {
              shopMoney { amount, currencyCode }
              presentmentMoney { amount, currencyCode }
            }
            lineItem { id }
          }
        }
        orderAdjustments(first: 100) {
          nodes {
            id
            amountSet {
              shopMoney { amount, currencyCode }
              presentmentMoney { amount, currencyCode }
            }
            taxAmountSet { shopMoney { amount, currencyCode } }
          }
        }
      }
    }
  }
}

Variables:

{
  "ids": [
    "gid://shopify/Order/7258900562216",
    "gid://shopify/Order/7258050036008",
    "gid://shopify/Order/7258312671528",
    "gid://shopify/Order/7258622787880",
    "gid://shopify/Order/7256423301416",
    "gid://shopify/Order/7257950486824",
    "gid://shopify/Order/7258555318568",
    "gid://shopify/Order/7257456214312",
    "gid://shopify/Order/7258446528808",
    "gid://shopify/Order/7255570776360"
  ]
}
1 Like

I mean you’ve answered your own question/issue here, no?

Using a large request fails, naturally. So you need to do it in batches/smaller queries.

This seems expected, the requests time out most likely.

Hey @shaheem - Luke’s very likely on the right track here. The nodes query with 10 orders, each pulling refunds(first: 200) with deeply nested transactions, line items, shipping lines, and adjustments can produce a very large response payload. When it exceeds internal limits, the API can’t return a well-formed GraphQL response and you get that raw 500 instead.

I hear you on the error messaging though. A structured error telling you the response exceeded size limits would be a lot more useful than a generic “Internal Server Error”.

To confirm what’s happening on our end, could you share the x-request-id header from one of your failing queries? That’ll let me check the logs and verify confirm what’s triggering the error.

In the meantime, reducing the batch size or splitting the nested fields into separate queries should get you unblocked. If you’re pulling refund data for a large number of orders regularly, the Bulk Operations API is worth a look since it’s designed for exactly this kind of heavy data export.

I already have a workaround (batching) live for this. Thought it was worth reporting here since GraphQL docs state that internal errors should be returned as HTTP 200 with a proper GraphQL errors array using the INTERNAL_SERVER_ERROR extension code, not a raw HTTP 500 with just {"errors": "Internal Server Error"} as a plain string.

Thanks Donal! Here’s the x-request-id from a failing request: 2028aed9-9289-4204-9ab8-62dd5b503f6a-1770641156

I’m already batching as a workaround, just thought it was worth reporting since a proper GraphQL error with a meaningful code would make this much easier to handle programmatically.

Regarding bulk operations. I did consider that route, but bulk queries only support a maximum nesting depth of two levels, and this query needs more than that, so the regular nodes query was the option I went with.

1 Like

I checked the logs and can confirm the query is generating a very large number of database queries across those 10 orders with all the nested refund data, and the request is hitting the server-side timeout before it can finish. When that timeout is hit, the process is forcefully terminated, which is why you get the raw 500 instead of a structured GraphQL error. The server doesn’t get a chance to compose a proper response before it’s killed.

Your point about wanting a meaningful error code is totally fair. Ideally the API would detect the approaching timeout and return a structured error you could handle programmatically, rather than a generic 500. I’ll raise that feedback with the relevant team.

Thanks for flagging!

1 Like