Solving Shopify Admin API Discount Errors: 'Variable $id Invalid Value' Explained
Hey store owners!
As someone who spends a lot of time diving into the Shopify community forums, I often come across really common, yet frustrating, issues that many of you face when trying to automate things with the Admin API. One such issue recently caught my eye, and it's a perfect example of how a small misunderstanding in how you interact with the API can lead to a big headache.
The problem? An error message that reads: Exception: Mutation had errors: "Variable $id of type ID! was provided invalid value". Sounds cryptic, right? But don't worry, the community quickly jumped in to clarify what's going on, and I'm here to break it down for you.
The Root Cause: Create vs. Update & Missing IDs
This particular error popped up when a store owner, ctevan, was trying to use the discountCodeBasicUpdate mutation. Essentially, they were trying to modify a discount, but the API was complaining about a missing or invalid id.
It's like trying to tell someone to 'update that document' without telling them *which* document you're referring to. The API needs a unique identifier, often called a Global ID (GID), to know exactly which discount you intend to modify.
Maximus3, another sharp community member, quickly hit the nail on the head by asking, "Where’s the discount GID?" This question perfectly highlights the core issue: if you're updating something, the system needs to know its unique ID.
The First Fix: Choosing the Right Mutation
Moeed, a true Shopify expert, provided the crucial insight. He pointed out that based on ctevan's input (which included a new code, title, and usage limit), it looked more like they were trying to *create* a new discount, not update an existing one. If that's the case, the correct mutation to use is discountCodeBasicCreate, not discountCodeBasicUpdate.
Think of it this way:
discountCodeBasicCreate: You use this when you want to make a brand new discount. You provide all the details, and Shopify gives it a unique ID.discountCodeBasicUpdate: You use this when you want to change an existing discount. For this to work, you *must* provide the specificid(GID) of the discount you want to change.
So, the first step is always to ask yourself: am I creating something new or modifying something that already exists?
Addressing Customer Eligibility: customerSelection is Key
Moeed also caught a second, equally important, syntax issue in ctevan's original input. The field context.customers isn't valid for specifying customer eligibility on a DiscountCodeBasicInput. Instead, you need to use the customerSelection field.
This is a common gotcha because API fields and structures can evolve or have specific requirements for different objects. It's vital to refer to the latest Shopify Admin API documentation to ensure you're using the correct fields and nested structures.
Putting It All Together: Your Corrected Discount Creation Input
Based on Moeed's expert advice, here's how the corrected input for discountCodeBasicCreate should look, fixing both the mutation type and the customer eligibility syntax. I'll include ctevan's original input first for comparison, then Moeed's corrected version. Notice the context versus customerSelection difference and the absence of an id for the discount itself in the create mutation.
Original Input (for Update, but missing ID & incorrect customer eligibility):
{
"basicCodeDiscount": {
"title": "{{ order.name }}",
"appliesOncePerCustomer": true,
"code": "{{ order.name }}",
"usageLimit": 1,
"context": {
"customers": {
"add": [
"{{ order.customer.id }}"
]
}
},
"customerGets": {
"value": {
"discountAmount": {
"amount": "25.00",
"appliesOnEachItem": false
}
},
"items": {
"products": {
"productsToAdd": [
"gid://shopify/Product/9617924784413"
]
},
"all": false
},
"appliesOnOneTimePurchase": true,
"appliesOnSubscription": false
}
}
}
Corrected Input (for Creating a New Discount):
{
"basicCodeDiscount": {
"title": "{{ order.name }}",
"appliesOncePerCustomer": true,
"code": "{{ order.name }}",
"usageLimit": 1,
"customerSelection": {
"customers": {
"add": [
"{{ order.customer.id }}"
]
}
},
"customerGets": {
"value": {
"discountAmount": {
"amount": "25.00",
"appliesOnEachItem": false
}
},
"items": {
"products": {
"productsToAdd": [
"gid://shopify/Product/9617924784413"
]
},
"all": false
},
"appliesOnOneTimePurchase": true,
"appliesOnSubscription": false
}
}
}
You can see how context was replaced by customerSelection, and the rest of the discount details are correctly structured for creation. Moeed's advice was simply to "Just swap the mutation to discountCodeBasicCreate and this should work straight away."
Step-by-Step Action Plan
If you're running into a similar Variable $id of type ID! was provided invalid value error when dealing with discounts, here's what to do:
- Determine Your Intent: Create or Update?
- If you want to make a new discount, use the
discountCodeBasicCreatemutation. - If you want to modify an existing discount, use the
discountCodeBasicUpdatemutation, and make sure you are passing the correct Global ID (GID) of that discount as a variable to your mutation call. This GID typically looks something likegid://shopify/DiscountCodeBasic/123456789.
- If you want to make a new discount, use the
- Verify Customer Eligibility Syntax: Always use
customerSelectionfor defining which customers are eligible for the discount. Avoid usingcontext.customersfor this purpose inDiscountCodeBasicInput. - Review Your Payload: Double-check that all fields in your JSON payload match the expected structure for your chosen mutation (
createorupdate) as per the latest Shopify Admin API documentation. - Test Thoroughly: Always test your API calls in a development or staging environment before deploying to your live store.
A Look at the Actual Run Input
For those of you who like to dig deeper, ctevan also shared the actual input that was being run, which highlighted the problem even more clearly:
{
"mutation_name": "discountCodeBasicUpdate",
"mutation_input": "{
"basicCodeDiscount": {
"title": "#292491",
"appliesOncePerCustomer": true,
"code": "#292491",
"usageLimit": 1,
"context": {
"customers": {
"add": [
"gid://shopify/Customer/7789058687261"
]
}
},
"customerGets": {
"value": {
"discountAmount": {
"amount": "25.00",
"appliesOnEachItem": false
}
},
"items": {
"products": {
"productsToAdd": [
"gid://shopify/Product/9617924784413"
]
},
"all": false
},
"appliesOnOneTimePurchase": true,
"appliesOnSubscription": false
}
}
}",
"api_version": "2026-01",
"hydration_type_patch": "{}"
}
This shows "mutation_name": "discountCodeBasicUpdate" which explicitly confirms the intent was an update, but the payload inside mutation_input didn't contain the necessary id for the discount itself, leading to the error. This also shows the incorrect context field being used for customer eligibility.
This community discussion is a fantastic reminder that even experienced developers can sometimes get tripped up by specific API requirements. It highlights the importance of understanding the exact purpose of each mutation (create vs. update) and paying close attention to the expected input structure. Don't be afraid to lean on the Shopify community or the official API documentation when you hit a wall – often, the solution is simpler than it seems once you get that crucial insight!