App dev connects to the wrong dev store when one store's domain is a substring of another's (storeByDomain returns first fuzzy-search hit)

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

shopify app dev --store example-store.myshopify.com connects to example-store.myshopify.com. Cached dev store values (.shopify/project.json, [build].dev_store_url in shopify.app.toml) resolve to the store with that exact domain. Archived stores are never selected.

Actual behavior

In an org (on the next-gen dev platform) with two dev stores where one .myshopify.com domain is a substring of the other โ€” example-store.myshopify.com and turbo-example-store.myshopify.com โ€” the CLI connects to turbo-example-store.myshopify.com even when --store example-store.myshopify.com is passed explicitly. It then persists the wrong domain back into .shopify/project.json and [build].dev_store_url, so the misresolution self-reinforces on every subsequent run. In my case the wrongly-selected store is even archived โ€” archived stores are still returned by the search.

The only way to reach the intended store is --reset + interactive selection (the store picker is unaffected), but the very next plain shopify app dev resolves the now-cached exact domain through the same buggy lookup and reverts to the wrong store.

Root cause (verified against the CLI source, still present on main): AppManagementClient.storeByDomain in packages/app/src/cli/utilities/developer-platform-client/app-management-client.ts passes the domain to Business Platform accessibleShops as the free-text search: argument and returns stores[0] without checking for an exact domain match. search: is substring matching, so searching example-store.myshopify.com returns both stores, and the backend ranks turbo-example-store first. Suggested fix: stores.find((s) => s.shopDomain === normalizedDomain) ?? stores[0], and ideally exclude archived stores. The Partners client is not affected (its FindStoreByDomain query matches exactly); this only affects orgs migrated to the next-gen dev platform.

Reproduction steps

  1. In an org on the next-gen dev platform, have two dev stores where one domain is a substring of the other, e.g. example-store.myshopify.com and turbo-example-store.myshopify.com (the superstring store can even be archived).
  2. In an app project, run shopify app dev --store example-store.myshopify.com.
  3. The info banner reports Dev store: turbo-example-store.myshopify.com, and .shopify/project.json / [build].dev_store_url now contain the wrong domain.

(Which store wins depends on backend search ranking; in my org the superstring store consistently ranks first.)

Verbose output

2026-07-06T05:03:44.628Z: Sending "BusinessPlatform" GraphQL request:
  query FetchDevStoreByDomain($domain: String) {
  organization {
    id
    name
    accessibleShops(
      filters: {field: STORE_TYPE, operator: EQUALS, value: "app_development"}
      search: $domain
    ) {
      edges { node { id externalId name storeType primaryDomain shortName url __typename } __typename }
      __typename
    }
    currentUser { organizationPermissions __typename }
    __typename
  }
}

With variables:
{
  "domain": "example-store.myshopify.com"
}

to https://destinations.shopifysvc.com/organizations/api/unstable/organization/<org_id>/graphql
2026-07-06T05:03:44.849Z: Request completed in 221 ms
2026-07-06T05:03:44.850Z: Reading the content of file at .shopify/project.json...
2026-07-06T05:03:44.851Z: Writing some content to file at .shopify/project.json...

โ•ญโ”€ info โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚  Using shopify.app.test.toml for default values:                             โ”‚
โ”‚    โ€ข Org:             <my org>                                               โ”‚
โ”‚    โ€ข App:             <my app>                                               โ”‚
โ”‚    โ€ข Dev store:       turbo-example-store.myshopify.com                      โ”‚
โ”‚   You can pass `--reset` to your command to reset your app configuration.    โ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ

Operating system

macOS 26.5.2 (darwin-arm64), Node 22

CLI version

Reproduced on 3.88.1 and 4.3.0; the stores[0] logic is still present on main.

Hi @Eugene_404, I appreciate the detailed report. Iโ€™ve raised this with the team that owns the CLI so they can take a look. I canโ€™t give a timeline, but the detail you included makes it much easier for them to act on. Thanks for raising this here!

Hi @Eugene_404, quick update on this: The team investigated, identified the cause and have put up a fix:

Feel free to keep an eye on the PR to track its progress to release. Thanks again for reporting this, youโ€™ve made a real material impact on the CLI!