GQL Query won't use variables - React Remix

Topic summary

GraphQL query variables in a React Remix app using Shopify’s admin.graphql were not being applied, triggering “Variable $first of type Int! was provided invalid value.” Mutations and GraphiQL tests worked, suggesting a client-side variable formatting issue.

Key detail: Different GraphQL clients require variables to be sent in specific formats. The recommended structure follows Apollo’s convention with separate query and variables fields; client libraries usually handle this.

Resolution: Variables must be wrapped under a variables key when calling admin.graphql. Working code: pass { variables: { first: 10, after: afterCursor } } alongside the query. Reference: Shopify Admin API client docs (packages/api-clients/admin-api-client).

Context: The query paginates products (noting the 250-product page limit) by iterating with after cursors (endCursor) and collecting IDs. Images were used to illustrate that the server response didn’t reflect provided variables, supporting the diagnosis.

Outcome: Issue resolved with correct variable wrapping. Open question remains on whether to switch to Apollo; no consensus or decision was made. Technical note: GraphQL variables are placeholders defined in the query and supplied separately in the request body by the client.

Summarized with AI on December 30. AI used: gpt-5.

When making a GQL Query with variables, the variables won’t be used. Have I done something wrong? My code below:

import { authenticate } from "../shopify.server";

export const fetchAllProducts = async (request) => {
    try {
        const { admin } = await authenticate.admin(request);

        // let hasNextPage = true;
        let afterCursor = null;
        let allProducts = [];

        for (let i = 0; i <= 7; i++) {
            const response = await admin.graphql(`#graphql
                query allProducts($first: Int!, $after: String) {
                    products(first: $first, after: $after, reverse: true) {
                        edges {
                            node {
                                id
                            }
                        }
                        pageInfo {
                            hasNextPage
                            startCursor
                            endCursor
                        }
                    }
                }
            `, {
                first: 10,
                after: afterCursor
            });

            const { data } = await response.json();

            const products = data.products.edges.map(edge => edge.node.id);
            allProducts = [...allProducts, ...products];

            // hasNextPage = data.products.pageInfo.hasNextPage;
            afterCursor = data.products.pageInfo.endCursor;
        }

        return allProducts;
    } catch (error) {
        console.error('Error fetching products:', error);
        return [];
    }
};

Mutations with variables haven’t been a problem for me. Locally making the query with variables on the graphiql playground doesn’t cause any issues and returns expected result.

Server Logs:

Error fetching products: GraphqlQueryError: Variable $first of type Int! was provided invalid value  
1 Like

WITH VARIABLES

WITHOUT VARIABLES : The result is the same the server gives from my code. That’s why I believe that the inputted variables to the query aren’t being used.

Hey, I’ve tried that, unfortunately, same result. Is my code valid?

To get all products, assuming the store doesn’t have over 250 products. Theres a 250 product limit, so you’ll have to loop to get all products.

Hi @tajbowness ,

The way GraphQL variables need to be defined to be sent along with the query varies by client so you’d want to check the docs for whichever client library it is that you’re using.

The end result should be compatible with the Apollo server format [docs with an example] where the final POST body has separate ‘query’ and ‘variables’ fields to hold each of those things. This is usually handled behind the scenes by the client library.

Hope you have a great day

1 Like

Thanks for the insight. I’ve managed to fix it. Turns out the variables just had to be wrapped with braces, ay ay ay, I spent to long with this.

This is the solution.

const variables = {
    first: 10,
    after: afterCursor
}

const response = await admin.graphql(`#graphql
    query allProducts($first: Int!, $after: String) {
        products(first: $first, after: $after, reverse: true) {
            edges {
                node {
                    id
                }
            }
            pageInfo {
                hasNextPage
                startCursor
                endCursor
            }
        }
    }
`, { variables });

Documentation referred to: (Under, Getting Started > Query for a product)

[shopify-app-js/packages/api-clients/admin-api-client at main · Shopify/shopify-app-js · GitHub](shopify-app-js/packages/api-clients/admin-api-client at main · Shopify/shopify-app-js · GitHub)

Thanks again for the reply, the insight really helped out. I’m not using Apollo, I’m using what’s provided by shopify when you create the remix app template.

temp.PNG

Should I swap to Apollo?

2 Likes