Skip to content

fix: prevent premature config load for unconfigured projects in monorepo sub-directories#34129

Open
mschile wants to merge 5 commits into
developfrom
claude/laughing-grothendieck-eb2357
Open

fix: prevent premature config load for unconfigured projects in monorepo sub-directories#34129
mschile wants to merge 5 commits into
developfrom
claude/laughing-grothendieck-eb2357

Conversation

@mschile

@mschile mschile commented Jun 19, 2026

Copy link
Copy Markdown
Collaborator

Additional details

When an unconfigured project (no cypress.config.*) is opened directly into a testing type from a monorepo sub-directory, startup breaks in two ways that share a single root cause:

Going through the launchpad manually (cypress open → select a testing type) works in both cases, and git init in the sub-directory was a known workaround for both.

Root cause: The relevant-runs poller calls projectId() as soon as git commit shas are found. In a sub-directory with no local .git, those shas come from the parent repo, so the poller fires during startup and forces getProjectId()getConfig() to load a non-existent cypress.config.js. That throws CONFIG_FILE_REQUIRE_ERROR, leaves the lifecycle in an error state, and makes waitForInitializeSuccess() resolve false — so initializeProjectSetup() is skipped. For --component that skips CT framework auto-detection; for --e2e that skips the config scaffold (scaffoldTestingType/scaffoldE2E), so the config file is never created and the launchpad retries the failing config load indefinitely. git init worked around it because an empty repo has no shas, so the poller returns early.

Fix: getProjectId() now returns null when the project has no valid config file instead of forcing a config load. An unconfigured project has no projectId, and this matches the existing readyToInitialize gate that already restricts config loading to metaState.hasValidConfigFile. getConfig() is intentionally left unchanged — it's a shared accessor whose other callers rely on it loading the full config; the invariant being expressed ("unconfigured → no projectId") belongs at the getProjectId layer.

Steps to test

Component (#27410):

  1. Clone a repo with git history at the root and an unconfigured CT project in a sub-directory:
    git clone --branch 27410-cy-ct-detection https://github.com/MikeMcC399/github-action
    cd github-action/examples/cy-react-vite-ct
    npm ci
    
  2. npx cypress open --component (do not git init in the sub-directory).
  3. Confirm the setup wizard shows React.js (detected) / Vite (detected) rather than "Pick a framework".

E2E (#29544):

  1. Clone a repo with git history at the root and an unconfigured project in a sub-directory:
    git clone https://github.com/cypress-io/github-action
    cd github-action/examples/basic
    rm cypress.config.js
    npm ci
    
  2. npx cypress open --e2e (do not git init in the sub-directory).
  3. Confirm Cypress scaffolds cypress.config.js and reaches the browser-selection screen instead of hanging on "Initializing config…".

Verified manually against both repros on the built dev binary. For --component, the server-side wizard.framework was null ("Pick a framework") before the fix and resolves React.js + Vite after. For --e2e, before the fix the config IPC repeatedly threw CONFIG_FILE_REQUIRE_ERROR for the missing cypress.config.js and no file was scaffolded; after the fix the project scaffolds and proceeds. Confirmed git init in the sub-directory also works (the original workaround), and that the configured-project path is unchanged.

How has the user experience changed?

In a monorepo sub-directory with an unconfigured project:

  • cypress open --component now auto-detects the installed framework/bundler instead of showing "Pick a framework".
  • cypress open --e2e now scaffolds the config and continues to browser selection instead of hanging on "Initializing config…".

Before

  • --component: Front-end framework: Pick a framework
  • --e2e: hangs indefinitely on "Initializing config…"

After

  • --component: Front-end framework: React.js (detected) / Bundler: Vite (detected)
  • --e2e: config is scaffolded and the browser-selection screen is shown

PR Tasks

  • Is there an associated issue with maintainer approval for PR submission?
  • Have tests been added/updated?
  • [na] Has a PR for user-facing changes been opened in cypress-documentation?
  • [na] Have API changes been updated in the type definitions?

Note

Low Risk
Small, targeted guard in project lifecycle startup with unit tests; behavior for projects with a valid config is unchanged.

Overview
Fixes monorepo sub-directory opens where an unconfigured project (no cypress.config.*) skipped setup: --component missed framework auto-detection and --e2e could hang on "Initializing config…".

ProjectLifecycleManager.getProjectId() now returns null when metaState.hasValidConfigFile is false instead of calling getConfig(). That stops startup paths (e.g. Cloud relevant-runs polling after parent-repo git SHAs) from forcing a load of a missing config, which previously put the lifecycle in an error state and blocked initializeProjectSetup(). Configured projects still load config and return projectId as before.

Unit tests cover both branches; 15.17.1 changelog documents the fix (#27410, #29544).

Reviewed by Cursor Bugbot for commit bb1a112. Bugbot is set up for automated code reviews on this repo. Configure here.

When opening an unconfigured project straight into component testing
(cypress open --component) from a monorepo sub-directory, framework
detection was skipped and the user was asked to pick a framework even
though one was installed.

The relevant-runs poller calls projectId() as soon as git commit shas
are found. In a sub-directory with no local .git, those shas come from
the parent repo, so the poller fires during startup and forces
getProjectId() -> getConfig() to load a non-existent cypress.config.js.
That throws CONFIG_FILE_REQUIRE_ERROR, leaves the lifecycle in an error
state, and makes waitForInitializeSuccess() resolve false -- so
initializeProjectSetup() (and its CT framework auto-detection) is
skipped. git init in the sub-directory was a known workaround because an
empty repo has no shas, so the poller returns early.

getProjectId() now returns null when the project has no config file,
matching the existing readyToInitialize gate, instead of forcing a load.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
cypress-bot[bot]
cypress-bot Bot previously approved these changes Jun 19, 2026
@mschile mschile self-assigned this Jun 19, 2026
@cypress

cypress Bot commented Jun 19, 2026

Copy link
Copy Markdown

cypress    Run #71845

Run Properties:  status check failed Failed #71845  •  git commit bb1a112257: chore: condense changelog entry
Project cypress
Branch Review claude/laughing-grothendieck-eb2357
Run status status check failed Failed #71845
Run duration 17m 10s
Commit git commit bb1a112257: chore: condense changelog entry
Committer Matthew Schile
View all properties for this run ↗︎

Test results
Tests that failed  Failures 3
Tests that were flaky  Flaky 2
Tests that did not run due to a developer annotating a test with .skip  Pending 13
Tests that did not run due to a failure in a mocha hook  Skipped 0
Tests that passed  Passing 1654
View all changes introduced in this branch ↗︎
UI Coverage  64%
  Untested elements 27  
  Tested elements 48  
Accessibility  98.94%
  Failed rules  0 critical   3 serious   1 moderate   0 minor
  Failed elements 18  

Tests for review

Failed  project-setup.cy.ts • 1 failed test • launchpad-e2e

View Output

Test Artifacts
Launchpad: Setup Project > switch testing types > takes the user to first step of ct setup when switching from app Test Replay Screenshots
Failed  error-handling.cy.ts • 2 failed tests • launchpad-e2e

View Output

Test Artifacts
... > automatically sources vite.config.js Test Replay Screenshots
... > automatically sources webpack.config.js Test Replay Screenshots
Flakiness  studio/studio-basic.cy.ts • 1 flaky test • app-e2e

View Output

Test Artifacts
Cypress Studio - Basic Functionality > updates an existing test with an action Test Replay Screenshots
Flakiness  run-all-specs-ct.cy.ts • 1 flaky test • app-e2e

View Output

Test Artifacts
run-all-specs-ct > run-all-specs-ct-vite > can run all specs with filter and live-reloadings Test Replay Screenshots

@mschile mschile changed the title fix: detect CT framework with --component in monorepo sub-directories fix: prevent premature config load for unconfigured projects in monorepo sub-directories Jun 19, 2026
@cypress-bot cypress-bot Bot dismissed their stale review June 19, 2026 03:20

Cursor Bugbot risk assessment is no longer Low Risk. Auto-approval dismissed; manual review required.

mschile and others added 2 commits June 18, 2026 21:27
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…othendieck-eb2357

# Conflicts:
#	cli/CHANGELOG.md
cypress-bot[bot]
cypress-bot Bot previously approved these changes Jun 19, 2026
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@cypress-bot cypress-bot Bot dismissed their stale review June 19, 2026 03:46

New commits pushed (auto-approval was for 1df8284, head is now f3ec558). Auto-approval dismissed pending Cursor Bugbot re-review of the new head SHA.

cypress-bot[bot]
cypress-bot Bot previously approved these changes Jun 19, 2026
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@cypress-bot cypress-bot Bot dismissed their stale review June 19, 2026 03:59

New commits pushed (auto-approval was for f3ec558, head is now bb1a112). Auto-approval dismissed pending Cursor Bugbot re-review of the new head SHA.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

open with --e2e in unconfigured monorepo hangs CT setup detection may fail if launchpad skipped (--component used to open)

1 participant