Product Meta fields with python Shopify API

Topic summary

A developer is encountering issues updating Shopify product metafields using Python. Initially using the REST API, they found that metafields of type “rich text” were not being retrieved, while “multi line text” metafields worked correctly—despite both being created programmatically with correct namespace and key values.

Key troubleshooting steps taken:

  • Verified metafields exist and are pinned in product admin
  • Enabled Storefront API access
  • Added logging to inspect raw JSON responses
  • Confirmed programmatic metafield creation requires GraphQL for rich text types

Current status:
The developer switched to GraphQL API and can now access the metafields successfully. However, they’re now stuck on the update operation, receiving “invalid json value” errors when attempting to update metafield values. Despite trying various approaches (escaped HTML, json.dumps(), ensuring string formatting), GraphQL continues rejecting the values with schema errors.

The discussion remains open with the developer seeking guidance on proper value formatting for GraphQL metafield updates.

Summarized with AI on October 28. AI used: claude-sonnet-4-5-20250929.

I am trying to update product meta fields using a python script via the Shopify API. I have tried so many things and made sure that the meta fields exist, used the correct name space and keys in the code. But they are somehow invisible to the code. The code retrieves other meta fields, but not the ones I want to update. The difference between the two groups of meta fields is that, the ones the code retrieves are created programmatically and are of the type multi line text and the others are also created by a python program but are of the type rich text field. Here is the code snippet that tries to extract meta fields:

def get_metafields(product_id, namespace, key :disappointed_face:
“”“Fetch metafields and filter by namespace and key.”“”
url = f"{SHOPIFY_BASE_URL}/products/{product_id}/metafields.json"
try:
response = retry_request(requests.get, url, headers=headers)
response.raise_for_status()
all_metafields = response.json().get(“metafields”, )
logging.debug(f"All metafields for product {product_id}: {all_metafields}") # Log all metafields

filtered = [
m for m in all_metafields
if m[“namespace”] == namespace and m[“key”] == key
]
logging.info(f"Found {len(filtered)} metafields for key ‘{key}’ and namespace ‘{namespace}’“)
return filtered
except requests.exceptions.RequestException as e:
logging.error(f"Error fetching metafields: {e}”)
if hasattr(e, ‘response’ :disappointed_face:
logging.error(f"Response content: {e.response.text}")
return

  • The meta fields are pinned and are visible on the product admin.
  • Storefront API access
    Definitions can be used in your custom storefronts and related apps is toggled on.

Had anyone like this problem before? Can someone help me or show a way to solve this problem?

Thanks in advance
Mikias

1 Like

Dear Emmishopy,

Thank you for taking the time to leave me some reply. I have tried to use
logging to return all the errors and printed the raw JSON file to see if
there is something in there. Still, I couldn’t see those meta fields. I
guess it is time to try GraphQL now. Actually, something that I have
learned when I am programmatically creating the meta fields, it is only
with GraphQL that I could create a rich text field type meta fields. I will
keep in touch if I need any help. I don’t see your reply on the community
page to like your reply any more, though.

Dear Emmyshopy,

I have changed from the rest API to the graphql API. Now I am able to access the product meta fields. But I am stuck with updating the meta fields. I keep on getting invalid json value for the metafields value. I have tried escape html, json.dumps() and numerous other ways to pass the metafield values, but I couldn’t get a success. Some times I get schema error. The documentatiin says we have to pass the values as a string, but even though I have a string value in python code, graphql some how doesn’t recognise it as a string. Do you think you can help with that? Any tips from any one who encountered this and solved it?

Thanks in advance.