`read_all_orders` can't be used as an optional scope on an unpublished app

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?

App

Expected behavior

As an unpublished app, with read all orders access granted, I expect to be able to use it as an optional scope

Actual behavior

(await shopify.scopes.query()).optional.includes(“read_all_orders”)
// expected: true
// actual: false

Requesting it directly returns Shopify’s own view of the declared set — the TOML list minus read_all_orders:

RequestGrantUserError: The requested optional scopes should be a subset of
the declared optional scopes: [read_orders, write_orders, read_customers,
write_customers, read_products, write_products, read_script_tags,
write_script_tags, read_locales, write_discounts, customer_read_customers,
write_draft_orders, read_merchant_managed_fulfillment_orders, read_locations]

### Reproduction steps
1. Partner Dashboard → request **Read all orders** for the unpublished app. Approved (`Status: Granted — auto granted scope`).

2. Add it to the config:

```toml
[access_scopes]
scopes = ""
optional_scopes = ["read_orders", "write_orders", "read_all_orders", ...]
  1. shopify app deploy -c <config> → succeeds, new version active.

  2. In the embedded admin:

    (await shopify.scopes.query()).optional.includes("read_all_orders")
    // expected: true
    // actual:   false
    
  3. Requesting it directly returns Shopify’s own view of the declared set — the TOML list minus read_all_orders:

    RequestGrantUserError: The requested optional scopes should be a subset of
    the declared optional scopes: [read_orders, write_orders, read_customers,
    write_customers, read_products, write_products, read_script_tags,
    write_script_tags, read_locales, write_discounts, customer_read_customers,
    write_draft_orders, read_merchant_managed_fulfillment_orders, read_locations]
    
  4. Repeat steps 2–4 on the published app → the scope appears in optional, the merchant grants it through the standard modal, and the full order history becomes retrievable.

Verbose output

Not relevant, the deployment works just fine and the shopify dev dashboard shows that the read_all_orders is present.

Hey @Dylan, I had a quick look into this and your expectation aligns with what I have found so far. I have a couple of things for you to check:

  1. Confirm the client_id in the config used with shopify app deploy matches the app whose API access page shows read_all_orders as granted.
  2. Confirm the version containing read_all_orders shows as the released version, not just created.
  3. Check how the unpublished app was created - a Partner custom app app versus a merchant owned custom app created in the Dev Dashboard or store admin. That “auto granted scope” label may mean the scope is coming from a grant mechanism rather than your config file.

If all three check out and scopes.query() still returns the reduced list, let me know and I’ll send a DM to get the app details from you for a closer look at what’s going on in the background - thanks!

Hi @Donal-Shopify , I have exactly the same situation with read_reports scope. Everything works with the production app.

Hi @irek.khasianov, thanks - that’s a useful data point. The same unpublished-versus-production split showing up on read_reports too suggests this isn’t specific to read_all_orders or its auto-grant handling, and points more toward how version content gets assembled for unpublished apps.

I’ll send you both a DM to gather more details - thanks!

Hi @irek.khasianov, thanks for the extra details via DM - they helped me narrow down what’s likely what’s happening on your install.

Your development install is resolving its optional scopes from an older dev deployment that predates your read_reports addition, so scopes.query() keeps returning the old set and the request fails the declared-subset check even though the released version declares the scope. I verified this end to end on a test app: releasing a version with the new scope doesn’t move a dev install onto that version, and restarting the dev server alone doesn’t either.

The fix is to add the scope to optional_scopes in the config your dev session runs from and start a fresh shopify app dev session, then re-query and request:

[access_scopes]
optional_scopes = ["read_reports"]

That populated the optional set and the grant went through the standard consent modal on my test app.