`theme dev` silently adopts a stored `store auth` session without checking theme scopes, breaking theme commands for OAuth users

I have reproduced the issue on the latest CLI version.

Yes, I am on the latest version

I have searched existing posts and this report is not a duplicate.

Yes, this isn’t a duplicate

In which of these areas are you experiencing a problem?

Theme

Expected behavior

theme dev should behave like theme pull and theme push: only use a stored store-app session if it actually has the theme scopes the command needs, and otherwise fall back to the OAuth session from shopify auth login.

Actual behavior

Hi team, thanks for all the work on CLI 4.x. I have hit what looks like a regression in how theme commands pick their auth session, and I believe it will affect anyone who uses both the new shopify store commands and shopify theme dev on the same store.

After running shopify store auth on a store with data scopes only (products, inventory, orders), shopify theme dev started failing even though I am authenticated with a staff account via shopify auth login that has full theme access. Two failure modes, depending on the stored token’s state: if the stored store auth token has expired, theme dev fails with a 401 on the publicApiVersions version handshake (see verbose output below); if the token is fresh, it fails with “The authenticated account or access token is missing read_themes access scope.”

Meanwhile theme pull and theme push keep working fine with the same login. Running shopify auth logout and shopify auth login again does not help, which makes this very confusing to debug.

Root cause (from reading the source on main): in packages/theme/src/cli/utilities/theme-command.ts, createSession() prefers a stored store-app session (from getCurrentStoredStoreAppSession) when hasRequiredStoreAuthScopes(storedSession.scopes) passes, and only falls back to ensureAuthenticatedThemes otherwise.

  • pull.ts overrides storeAuthScopes() to ['read_themes'] and push.ts to ['read_themes', 'write_themes'], so they correctly reject a data-only session and fall back to OAuth.
  • dev.ts has no storeAuthScopes() override, so it inherits the base [] and accepts any stored store-app session regardless of scopes.

Two smaller issues compound it: getCurrentStoredStoreAppSession() does not check expiresAt, and adminSessionFromStoreAuthSession() returns a session with no refresh handler, so an expired token is sent as-is and produces the raw 401. Also, hasRequiredStoreAuthScopes returns true for an empty stored scopes array, so an empty-scope session would be accepted by every theme command.

This behavior appears to come from the “Use stored store auth scopes for theme auth” change (June 2026), and is still present on main as of this post (also checked the 4.5.2 release notes).

Impact: anyone who uses shopify store commands for data operations and shopify theme dev for theme development on the same store will have theme dev break every time a store-auth token is minted or expires. Because shopify auth logout/login does not clear the store-auth storage, the usual recovery steps do not work, and the 401 variant gives no hint that a different credential store is involved.

Workaround: deleting the store’s entry from the store-auth local storage (~/Library/Preferences/shopify-cli-store-nodejs/config.json on macOS) restores OAuth fallback for theme commands, until the next store auth run recreates it.

Suggested fix: add a storeAuthScopes() override to dev.ts returning ['read_themes', 'write_themes'], matching push.ts. Checking expiresAt (or attaching the refresh handler) in the store-auth path would also turn the 401 failure mode into a clearer error.

Happy to provide full verbose logs (with identifiers redacted) if useful. Thanks!

Reproduction steps

  1. shopify auth login with a staff account that has full theme access (theme commands work).
  2. shopify store auth --store <store> --scopes read_products,write_products (any scope set without read_themes/write_themes).
  3. shopify theme dev --store <store> now fails with the scope error above; theme pull still works.
  4. Wait for the stored token to expire (about 24 hours) and theme dev fails with the 401 instead.

Verbose output

Error connecting to your store <store>.myshopify.com: GraphQL Error (Code: 401):
{"response":{"errors":"[API] Invalid API key or access token (unrecognized login or wrong password)",
"status":401,...,"request":{"query":"query publicApiVersions {...}"}} 401 undefined

Or, with a fresh stored token:

The authenticated account or access token is missing `read_themes` access scope.

Operating system

macOS (darwin-arm64)

CLI version

@shopify/cli/4.5.1 darwin-arm64 node-v26.5.0

Shell

zsh

Nodejs version

v26.5.0

What language and version are you using in your application?

N/A (Shopify theme CLI command)

Hey @Steve_Jiang :waving_hand: thanks for flagging this and for laying out the reproduction so thoroughly.

I was able to reproduce the same behaviour on CLI 4.5.2 as well, and I’m digging into this more. I’ll follow up in this thread as soon as I have more information.

I was able to reproduce and resolve this issue on Shopify CLI 4.5.2.

In my case, the Shopify account itself had the required access to the store and themes, and shopify auth logout / shopify auth login completed successfully. However, theme dev continued to fail with:

The authenticated account or access token is missing `read_themes` access scope.

What I found

I checked for stored store authentication:

shopify store auth list

The affected store was listed there.

I then found the stored store-auth configuration at:

%APPDATA%\shopify-cli-store-nodejs\Config\config.json

The stored session had these scopes:

write_products
write_inventory
read_locations

but did not have:

read_themes
write_themes

This explains why theme dev was failing.

Fix

The following steps resolved the issue:

# 1. Confirm the Shopify CLI version
shopify version

# 2. Check for stored store-auth sessions
shopify store auth list

# 3. Back up the existing store-auth configuration
Copy-Item `
  "$env:APPDATA\shopify-cli-store-nodejs\Config\config.json" `
  "$env:APPDATA\shopify-cli-store-nodejs\Config\config.json.backup"

# 4. Remove the stale store-auth configuration
Remove-Item "$env:APPDATA\shopify-cli-store-nodejs\Config\config.json"

# 5. Verify that the stored store-auth session is gone
shopify store auth list

# 6. Re-authenticate the Shopify account
shopify auth logout
shopify auth login

# 7. Test theme access
shopify theme list --store=YOUR-STORE.myshopify.com

# 8. Start theme development
shopify theme dev --store=YOUR-STORE.myshopify.com

After clearing the stored store auth session and re-authenticating, shopify theme list and shopify theme dev worked normally again.

Why it worked previously

The stored store auth session did not necessarily need read_themes / write_themes. It may have been created earlier for another CLI operation that only required product, inventory, or location scopes.

The problem appears to be that Shopify CLI 4.5.2 can reuse an existing store-auth session with insufficient scopes for theme dev, instead of using the normal Shopify account authentication that has the required theme access.

So this does not necessarily indicate that the Shopify account permissions were changed or that the original store-auth token was incorrectly created.

Affected version: Shopify CLI 4.5.2.

Note: Do not share the contents of config.json, as it may contain access and refresh tokens.

Just a heads up to say that this will be fixed in the next CLI release. Thanks for the report!