Skip to content

test(e2e): onboarding flakes waiting for the three enabled free models (#2431 follow-up) #2436

Closed

Description

@GabrielDrapor

Symptom

e2e_shard (1/2) fails in e2e/onboarding.spec.ts at the enabled-models poll:

expect(received).toEqual(expected)
  "enabledModelIds": [
    "nemotron-3-ultra-free",
-   "mimo-v2.5-free",
-   "deepseek-v4-flash-free",
  ],
Call Log: Timeout 10000ms exceeded while waiting on the predicate

Observed three times today:

The state is not slow-arriving — the poll runs 10s and enabledModelIds stays ["nemotron-3-ultra-free"], i.e. some writer produced a nemotron-only connection and nothing upgrades it afterwards.

Suspicion

A first-run race between the writers of opencode-free:

  • background bootstrap (app-lifecycle.ts — seeds v3 with the three models when the store is empty, or migrates via resolveOpenCodeFreeBootstrapMigration)
  • whatever creates/updates the connection during the onboarding save flow (保存供应商 on a fresh profile)

resolveOpenCodeFreeBootstrapMigration only recognizes two untouched shapes (v1 big-pickle, v2 nemotron + extras.version 2). If the onboarding-era writer lands a nemotron-only connection after the migration pass has already run (or in a shape the matcher doesn't recognize — e.g. no extras), the connection is permanently stuck at one model and the test's expectation can never be met — matching the 10s-flat poll.

Notes

Activity

  1. GabrielDrapor commented on Aug 7, 2026

    @GabrielDrapor
    ContributorAuthor

    Update — this is not a timing flake; it reproduces deterministically in isolation on macOS at main tip (npx playwright test e2e/onboarding.spec.ts --workers=1 fails 3/3 locally). CI's occasional green is the race landing the other way.

    Root cause, pinned

    Probed the connection right after onboarding's 保存供应商 (fresh profile):

    {
      "slug": "opencode-free",
      "defaultModel": "nemotron-3-ultra-free",
      "enabledModelIds": ["nemotron-3-ultra-free"],
      // no extras — no makaBootstrap version marker
      // createdAt === updatedAt — created in one shot by the save
    }

    The writer is the generic add-provider path, not the bootstrap seed: provider-add-form.tsx calls bridge.create({ slug, name, providerType, defaultModel, … }) with no enabledModelIds and no extras, and the create handler completes the shape to [defaultModel]. Two consequences:

    1. The v3 seed (OPENCODE_FREE_DEFAULT_ENABLED_MODELS, three models) never applies — app-lifecycle.ts only seeds when the store is empty, and by then it isn't.
    2. resolveOpenCodeFreeBootstrapMigration can never repair it: the shape matcher requires either v1 (big-pickle) or v2 (nemotron + extras.makaBootstrap.version === 2), and this connection has no extras. It is permanently stuck at one model.

    So whenever the user (or the e2e) reaches the save button before the background bootstrap wins the race, the three-model expectation from #2431 can never be met.

    Fix options

    • Narrowest: when the add-form / connections:create path creates providerType: 'opencode-free', source the full v3 seed shape (enabledModelIds + extras marker) from bootstrap-connections.ts — one exported helper, single source of truth.
    • Alternative: teach the migration to also recognize the extras-less nemotron-only shape as v2-equivalent (risks matching a user who deliberately trimmed to one model — the marker exists precisely to avoid that, so the first option seems safer).

    Happy to send the PR for the first option if useful.

  2. GabrielDrapor commented on Aug 7, 2026

    @GabrielDrapor
    ContributorAuthor

    Fixed by #2443 (fills the omitted enabledModelIds at the connection-store create seam). Verified locally on main tip: the previously deterministic failure now passes 4/4 (npx playwright test e2e/onboarding.spec.ts --workers=1), and #2418's CI — which was blocked on this — is green after rebasing. Closing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions