Help new errors api: "extensions": { "code": "GRAPHQL_VALIDATION_FAILED"

I all of a sudden started having issues with code that has been stable and working every day for over a year. So I tested a simple query through postman and the api playground. I now get

“errors”: [
{
“message”: “Cannot query field "items" on type "Board".”,
“locations”: [
{
“line”: 6,
“column”: 5
}
],
“extensions”: {
“code”: “GRAPHQL_VALIDATION_FAILED”
}
}
],
“account_id”: xxx
}

for a query as simple as:

{
boards(ids: 4017433669) {
id
name
items (limit: 10) {
id
name
column_values {
id
value
text
}
subitems {
id
name
column_values {
id
value
text
}
}
}
}
}

My real code returns a similar error

(Can’t get |data| of {account_id:xxx, errors:{{message:“Invalid GraphQL request”, |extensions|:{details:“failed to get the request body: error reading a body from connection: Invalid gzip header”, code:“INVALID_GRAPHQL_REQUEST”}}}}.-1728)

You’re not using items_page which is now how you get items without item IDs from a board. The requirement to use items_page though started October 2023 - so its unlikely the query you provided has been working for over a year.

Another thing is currently in 2024-10 the data object is not returned on errors. It should be in 2025-01. To be spec compliant the data object must be returned even if its an empty object or a null. You’re using a spec compliant GraphQL client which is throwing error on that aspect.

Ok so the test I tried running was a default from api playground and the first one I found in Postman. My issue with the actual code that’s been working gives this error:

Can’t get |data| of {account_id:xxxx, errors:{{message:“Invalid GraphQL request”, |extensions|:{details:“failed to get the request body: error reading a body from connection: Invalid gzip header”, code:“INVALID_GRAPHQL_REQUEST”}}}}. -1728

What library (and language) are you using to make the request itself?

The error message you posted seems entirely unrelated to the query you posted (are they even related?)

It appears to be an issue with the library making the call sending an invalid gzip header? Or not interpreting what is received correctly.

There is an extra } at the end. Then after that, the owner field is deprecated and has been replaced with owners and creator.

Just putting stuff into the playground instead of using Postman will help you solve a lot of this - as the playground knows the GraphQL schema and it will actually tell you the issues. I’d say do that first.

1 Like

Agree with @codyfrisch - always use the playground to validate that your GraphQL actually works before introducing more problems.

1 Like

@codyfrisch I was in panic and kept having to convert my code from c to graphql and missed the obvious error in the extra bracket. Thank you for pointing that out. The main issue was in my code that I hadn’t updated since April, all of sudden stopped working and it was the owner field for sure causing the issue which I didn’t even need. I deleted it from the query but crazy it still works in postman and api playgound but stopped working directly in my post to the api.

Here was my query in literally every function I built:
query {
boards {
id
name
board_folder_id
board_kind
updated_at
communication
owner {
id
name
}
}
}

Now the new one is simple and works
query {
boards {
id
name
}
}

Do you have any idea why would work in playground and in postman but not directly to the api?

I’m getting an internal server error from some of my requests as well actually. I have an internal item view set up that works just fine with an item with like 5 updates, but with 40 it errors out with a “internal server error” and then spits back a GraphQL validation error. However, I’ve also got a second app I developed that runs regularly using pagination and is also dying currently, but does not include “owner”.

const fetchItemsWithPagination = async (groupIds, retryCount=0) => {
    try{
        let cursor = null;
        let allItems = [];
        const limit = 100;
        const updateLimit = 20;

        // Convert the board ID to a string to match the ID! type expected by the API
        const boardId = MONDAY_BOARD_ID.toString();

        // Ensure groupIds is not null and is an array of strings
        if (!groupIds || groupIds.length === 0) {
            throw new Error('No valid group IDs provided.');
        }

        do {
            // Determine which query to use based on whether we have a cursor
            const query = cursor ? `
                query {
                    next_items_page(
                        limit: ${limit}, 
                        cursor: "${cursor}"
                    ) {
                        cursor
                        items {
                            id
                            name
                            group {
                                id
                                title
                            }
                            column_values(ids: ["color9", "text6", "date50", "date", "date05"]) {
                                id
                                text
                                value
                            }
                            updates(limit: ${updateLimit}) {
                                id
                                text_body
                                created_at
                                creator {
                                    name
                                }
                                replies {
                                    id
                                    text_body
                                    created_at
                                    creator {
                                        name
                                    }
                                }
                            }
                        }
                    }
                }
            ` : `
                query {
                    boards (ids: ${boardId}){
                        items_page(
                            limit: ${limit}, 
                            query_params: {
                                rules: [{
                                    column_id: "group",
                                    compare_value: ${JSON.stringify(groupIds)},
                                    operator: any_of
                                }]
                            }
                        ) {
                            cursor
                            items {
                                id
                                name
                                group {
                                    id
                                    title
                                }
                                column_values(ids: ["color9", "text6", "date50", "date", "date05"]) {
                                    id
                                    text
                                    value
                                }
                                updates(limit: ${updateLimit}) {
                                    id
                                    text_body
                                    created_at
                                    creator {
                                        name
                                    }
                                    replies {
                                        id
                                        text_body
                                        created_at
                                        creator {
                                            name
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            `;

            // Log the query to the console
            //console.log("GraphQL Query:", query);

            const response = await axios.post('https://api.monday.com/v2', {
                query: query
            }, {
                headers: {
                    Authorization: MONDAY_API_KEY
                }
            });

            const result = response.data;
            const items = cursor ? result.data.next_items_page.items : result.data.boards[0].items_page.items;
            const newCursor = cursor ? result.data.next_items_page.cursor : result.data.boards[0].items_page.cursor;
            allItems = [...allItems, ...items];
            cursor = newCursor;

        } while (cursor);

        return allItems;
    }
    catch (error) {
        if (error.response && error.response.status === 504 && retryCount < 6) {
            const delay = Math.min(60000, Math.pow(2, retryCount) * 1000); // exponential backoff, max 1 minute
            console.warn(`504 error. Retrying after ${delay / 1000} seconds...`);
            await new Promise(resolve => setTimeout(resolve, delay));
            return fetchItemsWithPagination(groupIds, retryCount + 1); // retry the request
        } else {
            console.error('Error fetching items with pagination:', error);
            sendErrorEmail(`Error fetching items with pagination: ${error}`);
            return null;
        }
    }
};

It is interesting that this just started becoming an issue yesterday afternoon…

1 Like

If your issue is another “deprication” issue then I’m gonna snap. Chasing deprication unnecessarily on something going from owner to owners is kind of rediculous. Why not add owners and leave owner or return both with either instead of eliminating something and having it roll out phased so much it’s hard to tell. Don’t get me wrong…I love Monday and their team and community is great! Just why not think about ways to keep deprication from being absolute unless necessary.

I think the issue may be related to the updates in some way - at least for me. If I run an API call like this…:

query {
    boards (ids:[boardIdHere] ){
        items_page(
            limit: 100, 
            query_params: {
                rules: [{
                    column_id: "group",
                    compare_value: ["new_group2855"],
                    operator: any_of
                }]
            }
        ) {
            cursor
            items {
                id
                name
                group {
                    id
                    title
                }
                column_values(ids: ["color9", "text6", "date50", "date", "date05"]) {
                    id
                    text
                    value
                }
                updates(limit: 20) {
                    id
                    text_body
                    created_at
                    creator {
                        name
                    }
                    replies {
                        id
                        text_body
                        created_at
                        creator {
                            name
                        }
                    }
                }
            }
        }
    }
}

Everything works great. If I bump that update limit up to something like 40, it dies. Even requesting 1 item with a limit of 40 updates kills it.

Hey @dean_m,

I suggest opening a support ticket so our team can take a closer look at your queries to determine what is going on. Make sure to include as much information as possible to help get a resolution faster!

Best,
Rachel

If you’re having inconsistent behaviors I would recommend checking the api-version header you’re sending. If you don’t send the header it will use whatever is the current stable - but if you do send a header, it will use the specific version assuming its still in the maintenance release list. It is likely you’re specifying a version in one place, but not in another.

Wow…thats insane. You’re correct. I thought it defaulted to the stable release. No idea what version it was sending but your tip solved every error I had. The conspiracist in me thinks something just changed in the API this week and that it is now defaulting to another but holy moly…thanks. @aholtzhauer read his comment and give it a try!

just fyi my change in code was to use 2024-07 and works fine in 2024-04. Whatever version it was using reported Invalid gzip header being sent back.

Just to clarify… did you already have the API version specified in your request? Based on the link provided by Cody, the maintenance version is now 2024-07 and the current version is 2024-10.

My API calls never specify an API version, which means they’re always calling for the current version. I guess I technically could add in the parameter to use the maintenance 2024-07 version, but eventually that will be sunset and 2024-10 will become the maintenance version, in which case any un-fixed issues will arise again I believe.

@dean_m So if you have now specified “2024-07” as your version and the issue became fixed, I would suspect that the issue will come back in a few months when the current version becomes the maintenance version and the other older versions become deprecated.

From the link Cody sent:

2024-10 is the issue. I tested with that and got the errors. Error says it has issues with gzip header being incomplete or corrupted when it returns to result or but possibly because it returns internal server error and there is no info. @aholtzhauer no I was not previously specifying.

2024-10 went live this month. It focused on tightening up error handling and being more strict on the schema and parsing.

Its a bit of a pain, but ultimately it will make things more stable and reliable by catching things in earlier stages of the API where its easier to return meaningful errors.

That said its possible you found some gaps in coverage - specifically with fields that were long deprecated and may not have been included in validation. I’d still open a case at the link provided by rachel.

So I have identified several ways to break the 2024-10 code and did not break the 2024-7 code and one very bizarre way of fixing…

This will error in 2024-10 as I had in mine:

var settings = {
  "url": "https://api.monday.com/v2",
  "method": "POST",
  "timeout": 0,
  "headers": {
    "Content-Encoding": "gzip",
    "API-Version": "2024-10",
    "Content-Type": "application/json",
    "Authorization": "xxx"
  },
 "data": JSON.stringify({
    "query": "query { boards (limit:1000) { id name board_folder_id board_kind}}"
  }),
};

$.ajax(settings).done(function (response) {
  console.log(response);
});

It errors:
"message": "Invalid GraphQL request", "extensions": { "details": "failed to get the request body: error reading a body from connection: Invalid gzip header", "code": "INVALID_GRAPHQL_REQUEST"

however if I change API Version to 2024-7 with this:

"API-Version": "2024-7"

No error. So here’s the issue, header should have been:

"Content-Transfer-Encoding": "gzip" instead of `"Content-Encoding": "gzip"

But for a strange twist if I change the url to this:

"url": "https://api.monday.com/v2/"

and put the Content-Encoding back:

"Content-Encoding": "gzip"

It now works! Not sure why they wouldn’t allow Content-Encoding over http as it is more efficient as far as I know in longer responses. Anyone have any feedback on why it’s not allowed or why adding a / to the end of the url allows it?

@DanielHai mentioning you in on this one, just for your awareness.