Unable to update Shopify product category via GraphQL productSet mutation

I’m trying to update a product’s category (Shopify Standard Product Taxonomy) in my store, but neither the GraphQL nor the REST Admin API calls seem to work. In both cases I got the success message but product category filed not updated on shopify.

GraphQL approach

   async function updateProductCategoryGraphQL(
  productId,
  newProductCategoryId,
  shopifyDomain,
  accessToken
) {
  const url = `https://${shopifyDomain}/admin/api/2025-04/graphql.json`;
  const headers = {
    'Content-Type': 'application/json',
    'X-Shopify-Access-Token': accessToken,
  };


  const productGid  = `gid://shopify/Product/${productId}`;
  const categoryGid = `gid://shopify/ProductTaxonomyNode/${newProductCategoryId}`;


  const mutation = `
    mutation setProductCategory($input: ProductSetInput!) {
      productSet(input: $input) {
        product {
          id
          category {
            id
            fullName
          }
        }
        userErrors {
          field
          message
        }
      }
    }
  `;


  const variables = {
    input: { id: productGid, category: categoryGid }
  };


  console.log('GraphQL payload:', JSON.stringify({ query: mutation, variables }, null, 2));


  try {
    const resp = await axios.post(url, { query: mutation, variables }, { headers });
    const body = resp.data;


    // 1) HTTP errors
    if (body.errors) {
      console.error('GraphQL HTTP errors:', body.errors);
      throw new Error(body.errors.map(e => e.message).join('; '));
    }


    // 2) Mutation‐level userErrors
    const ps = body.data?.productSet;
    if (!ps) {
      console.error('No productSet in response:', body);
      throw new Error('Missing productSet payload');
    }
    if (ps.userErrors?.length) {
      console.error('Mutation userErrors:', ps.userErrors);
      throw new Error(ps.userErrors.map(e => e.message).join('; '));
    }


    console.log('Updated product:', ps.product);
    return ps.product;


  } catch (err) {
    console.error('GraphQL error:', err.response?.data || err.message);
    throw err;
  }
}


// — How to run it —  
const myProductId            = 7892697907257;
const myNewProductCategoryId = 7447;
const myShopifyDomain        = 'your store.myshopify.com';
const myAccessToken          = process.env.SHOPIFY_ADMIN_ACCESS_TOKEN;


if (!myAccessToken) {
  console.error('Missing SHOPIFY_ADMIN_ACCESS_TOKEN in your env');
} else {
  updateProductCategoryGraphQL(
    myProductId,
    myNewProductCategoryId,
    myShopifyDomain,
    myAccessToken
  ).catch(() => console.error('— Failed to update product via GraphQL —'));
}

GraphQL result

`GraphQL HTTP errors: [
  {
    message: 'Invalid product_taxonomy_node_id',
    extensions: { code: 'INVALID_PRODUCT_TAXONOMY_NODE_ID' }
  }
]`

What I’ve verified

1.Both 7892697907257 (product) and 7447 (taxonomy node) exist in the Shopify Admin.

2.Admin API token has the write_products scope.

3.Tried root and leaf node IDs—still “Invalid product_taxonomy_node_id” in GraphQL.

Expected result

1.GraphQL: productSet returns the updated product with category.id = gid://shopify/ProductTaxonomyNode/7447.

Question

1.Am I using the correct mutation/input for GraphQL?

2.Is there an extra step or permission needed to assign taxonomy nodes?

**Links **

1 Like

Hey @clothovia :waving_hand: - as of API version 2024-04, ProductTaxonomyNode was replaced with TaxonomyCategory (there’s a bit more info on this here). In your mutation you’d want to use something like this:

{
  "input": {
    "id": "gid://shopify/Product/YOUR_PRODUCT_ID",
    "category": "gid://shopify/TaxonomyCategory/vp-2-3"
  }
}

The category IDs from the site here should be accurate though, but they have changed slightly (I don’t believe that Node ID you used is accurate as of 2024-04)

Hope this helps - let me know if I can clarify anything on our end!