A space to discuss GraphQL queries, mutations, troubleshooting, throttling, and best practices.
Hi, everyone.
I am following GraphQL Documentation and trying to update the ProductTaxonomy for my products. I have got my Product ID and also the Product Taxonomy ID and I have created the below function,
def update_product_taxonomy(product_gid, product_taxonomy_node_id):
mutation = """
mutation productUpdate($input: ProductInput!) {
productUpdate(input: $input) {
product {
id
productCategory {
productTaxonomyNodeId
}
}
userErrors {
field
message
}
}
}
"""
variables = {
"input": {
"id": f"gid://shopify/Product/{product_gid}",
"productCategory": {
"productTaxonomyNodeId": f"gid://shopify/ProductTaxonomyNode/{int(product_taxonomy_node_id)}"
}
}
}
headers = {
"Content-Type": "application/json",
"X-Shopify-Access-Token": token
}
response = graphql_request(GRAPHQL_URL, headers, mutation, variables)
if response['success']:
logging.info(f"Product {product_gid} taxonomy updated successfully to {product_taxonomy_node_id}.")
product_taxonomy_logs.append(f"Product {product_gid} taxonomy updated successfully to {product_taxonomy_node_id}.")
return True
else:
logging.error(f"Failed to update product {product_gid} taxonomy, errors: {response.get('errors', [])}")
product_taxonomy_logs.append(f"Failed to update product {product_gid} taxonomy, errors: {response.get('errors', [])}")
return False
I also have another generic function for GraphQL Requests, which I have given below,
def graphql_request(url, headers, query, variables, max_retries=2, retry_delay=2):
attempt = 0
while attempt < max_retries:
try:
response = requests.post(url, headers=headers, json={'query': query, 'variables': variables})
print("Request sent:", {'query': query, 'variables': variables}) # Log the request
if response.status_code == 200:
try:
json_data = response.json()
print("Response received:", json_data) # Log the response
if 'errors' in json_data: # Handle GraphQL errors
error_message = "; ".join([error['message'] for error in json_data['errors']])
logging.error(f"GraphQL error on attempt {attempt}: {error_message}")
# return {'success': False, 'errors': json_data['errors']}
else:
return {'success': True, 'data': json_data}
except json.JSONDecodeError as e:
logging.error(f"Failed to parse JSON response on attempt {attempt}. Error: {e}")
else:
logging.error(f"Received HTTP {response.status_code}, retrying... Attempt: {attempt}")
except requests.exceptions.RequestException as e:
logging.error(f"Request failed on attempt {attempt}. Error: {e}")
attempt += 1
time.sleep(retry_delay * (2 ** attempt)) # Exponential backoff
logging.error("Max retries exceeded.")
return {'success': False, 'errors': ['Max retries exceeded.']}
I am quite certain that the mutation and structure I am following is according to what is provided by productUpdate mutation but I am still getting an error:
Field 'productTaxonomyNodeId' doesn't exist on type 'ProductCategory'
Can anyone help in this regard? I am not sure what I am doing wrong.
Please find below my Request (that is being sent to API) and also the complete response I am getting.
Request sent
Request sent: {'query': '\n mutation productUpdate($input: ProductInput!) {\n productUpdate(input: $input) {\n product {\n id\n productCategory {\n productTaxonomyNodeId\n }\n }\n userErrors {\n field\n message\n }\n }\n }\n\n\n ', 'variables': {'input': {'id': 'gid://shopify/Product/9187042787610', 'productCategory': {'productTaxonomyNodeId': 'gid://shopify/ProductTaxonomyNode/3621'}}}}
Response Received,
Response received: {'errors': [{'message': "Field 'productTaxonomyNodeId' doesn't exist on type 'ProductCategory'", 'locations': [{'line': 7, 'column': 17}], 'path': ['mutation productUpdate', 'productUpdate', 'product', 'productCategory', 'productTaxonomyNodeId'], 'extensions': {'code': 'undefinedField', 'typeName': 'ProductCategory', 'fieldName': 'productTaxonomyNodeId'}}]}
Hey @hassanashas ,
Thanks for sharing the clear example. It really helps.
Comparing your request to our documentation, the issue is in the productCategory field that you're requesting to be returned.
The input fields are correct,
"productCategory": {
"productTaxonomyNodeId": "gid://shopify/ProductTaxonomyNode/3621"
}
The response fields are actually slightly different.
Changing your request to the following should resolve the error you are getting:
productCategory {
productTaxonomyNode {
id
}
Here's an example of a simplified mutation to demonstrate:
mutation ProductUpdate {
productUpdate(
input: {
id: "gid://shopify/Product/9187042787610"
productCategory: {
productTaxonomyNodeId: "gid://shopify/ProductTaxonomyNode/3621"
}
}
) {
product {
productCategory {
productTaxonomyNode {
id
}
}
}
}
}
Hope that helps
- Kyle G.
Developer Support @ Shopify
- Was this reply helpful? Click Like to let us know!
- Was your question answered? Mark it as an Accepted Solution
- To learn more visit Shopify.dev or the Shopify Web Design and Development Blog