`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)