- A Function sees only what its input query asked for. The input is a GraphQL query you declare up front, and there is no second lookup at runtime.
- The data model gets decided before the logic does. Discovering halfway through that you need one more field is a change to the query, the deployment and the tests — not a line of code.
- No network access. A Function cannot fetch a price, look up stock in another system, or call an API.
- Anything the rule depends on has to be in the input or in metafields before checkout begins. If the source of truth lives outside Shopify, the real design problem is getting it in, and the Function is the easy part.
- There is an instruction budget, and exceeding it is a hard failure rather than a slow response.
- The number to test against is the largest realistic cart, not the average one. Cost scales with cart size, so a Function that is comfortable in development can fail on the wholesale order that matters most.
- Discount Functions cannot create cart lines. Cart Transform can merge lines or expand one into components; neither invents a line that was not already there.
- "Add a free gift" and "price this bundle as a unit" are different problems with different answers, and which one you have been asked for is worth settling before any code is written.
- Whether a Function combines with other discounts is a configuration decision, not an implementation detail.
- It is the first thing a merchant asks about after launch. Deciding it deliberately is cheaper than discovering it from a support ticket.
- A rule a merchant will want to change does not belong in the code.
- Thresholds, tiers and product sets go in metafields with an admin surface. Hardcoding them turns every business decision into a developer deployment, which is the situation the Function was meant to end.