Every product has one bug that ages the person who found it by about a year in the space of a single afternoon. This is ours. It never touched a single dollar of anyone’s money, but for a few hours it felt like watching the whole payment stack quietly catch fire.
Here’s what actually happened: the Shopify Admin API started silently returning 403s for a subset of merchants. No error banner, no obvious pattern at first — just requests that should have worked, quietly failing. The eventual root cause was an access-token expiry edge case, and the fix that resolved it was passing a single parameter, expiring:1, on the relevant API calls.
Why did a one-flag fix take real debugging to find?
Because the symptom didn’t point at the cause. A 403 on an Admin API call looks like an authorization problem — a wrong scope, a revoked access, a permissions bug in our own code. It does not look like “this token is a specific kind of expiring token, and the request needs to say so explicitly.” We chased the obvious suspects first, because that’s what the error actually resembled. It took working backward from which merchants were affected, and what their tokens actually had in common, before the real shape of the problem showed up.
What the fix actually was
Once we found it, the change itself was small: pass expiring:1 so the API call correctly accounts for tokens that expire, instead of assuming the older, non-expiring token shape. It shipped as migration 0078. The real lesson wasn’t about the flag itself — it was how much debugging can hide behind a fix that, once found, looks embarrassingly simple.
What we’d tell someone hitting the same thing
If you’re integrating with an API that has more than one token type or auth flow, and you see 403s that don’t match the permissions you think you’ve granted, don’t assume the bug is where the error is pointing. Check whether the token itself is a different shape than the one your code was written against. That mismatch is invisible until you go looking for it specifically.
We’re building yoursignalstack in public, bugs included, because we’d rather you see the real process than a highlight reel. If you want to follow along, leave your email and we’ll let you know when it’s live.