Update: Root Cause Found - Translation Apps Registering on App Metafields
We’ve identified the actual root cause of this issue, and it’s not simply Liquid template caching or CDN staleness.
The Problem
When app metafield definitions have storefront: PUBLIC_READ access (which is required for theme app extensions to read them in Liquid), those metafields become visible in Shopify’s “Translate and Adapt” app and any third-party translation app installed on the store.
If the merchant (or a translation app) translates these metafields for a specific locale (e.g. Korean, Japanese, Spanish), Shopify starts serving the translated version of the metafield value on locale pages instead of the base value. This is by design for content that should be translated - but for app metafields that store operational JSON data (settings, variant IDs, selling plan configurations), this is bad.
Here’s why:
- App writes metafield with fresh data (e.g.
selling_plans JSON blob)
- Translation app has previously registered a translated version for locale X
- On locale X pages, Shopify serves the old translated value instead of the fresh base value
- The
outdated: true flag is set on the translation, but Shopify still serves it
- The app’s metafield updates never reach locale pages until the translation is removed
You can verify this by querying the translatableResource GraphQL API:
{
translatableResource(resourceId: "gid://shopify/Metafield/YOUR_METAFIELD_ID") {
translations(locale: "ja") {
key
value
outdated
}
}
}
If translations returns results with outdated: true, that stale translated value is what’s being served on your locale pages.
Why There’s No Simple Prevention
- Metafield definitions do NOT have a
translatable capability toggle (unlike metaobject definitions which do)
- The only storefront access options are
PUBLIC_READ or NONE — there’s no “readable but not translatable” middle ground
- Any metafield with
PUBLIC_READ is automatically exposed to translation tools
The Solution
Since you can’t prevent translations from being registered, you need to detect and remove them. There are two approaches:
Approach 1: Delete and Recreate the Metafield (No Extra Scopes Needed)
Deleting a metafield removes its GID and all associated translations. Re-creating it assigns a new GID with no translations attached:
# For each affected metafield key:
shop.unset_metafield(key) # Deletes metafield + all its translations
shop.set_metafield(key) # Creates fresh metafield with new GID, no translations
This is the approach we’re using. We run a daily detection job that queries translatableResourcesByIds across all shops to find metafields with translations, then remediate by deleting and re-setting the affected metafields.
Approach 2: Use translationsRemove Mutation (Requires write_translations Scope)
If you have write_translations scope, you can surgically remove translations without recreating the metafield:
mutation {
translationsRemove(
resourceId: "gid://shopify/Metafield/YOUR_METAFIELD_ID"
translationKeys: ["value"]
locales: ["ja", "ko", "es"]
) {
userErrors { message field }
}
}
Detection: How to Find Affected Shops
Use translatableResourcesByIds with GraphQL aliases to batch-check all metafields across all locales in a single query per shop:
{
ko: translatableResourcesByIds(first: 50, resourceIds: ["gid://shopify/Metafield/123", "gid://shopify/Metafield/456"]) {
nodes { resourceId translations(locale: "ko") { key } }
}
ja: translatableResourcesByIds(first: 50, resourceIds: ["gid://shopify/Metafield/123", "gid://shopify/Metafield/456"]) {
nodes { resourceId translations(locale: "ja") { key } }
}
}
If any translations array is non-empty, that metafield has a registered translation for that locale.
Feature Request to Shopify
It would be very helpful if Shopify added a translatable capability to metafield definitions (similar to what exists for metaobject definitions) so that app developers can mark operational/config metafields as non-translatable while keeping them publicly readable.
The current behavior — where any PUBLIC_READ metafield is automatically exposed to translation tools — creates a class of bugs that’s difficult to detect and affects any app that stores structured/operational data in shop-level metafields with theme extension access.