cypress-io/cypress · error · Error

Invalid project path parameter: ${options.project}

Error message

Invalid project path parameter: ${options.project}

What it means

Thrown by the programmatic Module API cypress.run() when options.project fails isValidProject(). That helper (cli/lib/exec/run.ts:17) rejects boolean values and the string literals 'true', 'false', and '' because cypress run, unlike cypress open, does not support global mode and needs a real project folder. The check exists so a stray `cypress run --project false` (valid for open) fails fast instead of launching a meaningless run.

Source

Thrown at cli/lib/cypress.ts:25

import cliImport from './cli'

  /**
   * Opens Cypress GUI
   * @see https://on.cypress.io/module-api#cypress-open
   */
export function open (options: any = {}): any {
  options = util.normalizeModuleOptions(options)

  return openModule.start(options)
}

/**
 * Runs Cypress tests in the current project
 * @see https://on.cypress.io/module-api#cypress-run
 */
export async function run (options: any = {}): Promise<any> {
  if (!runModule.isValidProject(options.project)) {
    throw new Error(`Invalid project path parameter: ${options.project}`)
  }

  options = util.normalizeModuleOptions(options)
  tmp.setGracefulCleanup()

  const outputPath: string = tmp.fileSync().name

  options.outputPath = outputPath

  const failedTests = await runModule.start(options)
  const output = await fs.readJson(outputPath, { throws: false })

  if (!output) {
    return {
      status: 'failed',
      failures: failedTests,
      message: 'Could not find Cypress test run results',
    }

View on GitHub (pinned to 0d85fdc912)

Solutions

  1. Pass a concrete project path string, e.g. cypress.run({ project: process.cwd() }) or an absolute/relative directory path.
  2. If you actually want global mode, use cypress.open({ project: false }) instead of cypress.run().
  3. Sanitize the value before calling: ensure it is a non-empty string that is not 'true'/'false' before assigning it to options.project.

Example fix

// before
await cypress.run({ project: useGlobal ? false : process.cwd() })

// after
await cypress.run({ project: process.cwd() })
Defensive patterns

Strategy: validation

Validate before calling

import isValidProject from './cli/lib/exec/run'

// or inline the same checks the library uses:
function safeProject(p: unknown): string {
  if (typeof p === 'boolean' || p === '' || p === 'true' || p === 'false') {
    throw new Error(`Refusing to call cypress.run() with invalid project: ${String(p)}`)
  }
  return p as string
}

const project = safeProject(options.project)
await cypress.run({ ...options, project })

Type guard

function isValidProjectPath(v: unknown): v is string {
  return typeof v === 'string' && v !== '' && v !== 'true' && v !== 'false'
}

Try / catch

try {
  await cypress.run({ project })
} catch (e) {
  if (e instanceof Error && e.message.startsWith('Invalid project path parameter')) {
    // surface a friendlier error pointing at how project was computed
  }
  throw e
}

Prevention

When it happens

Trigger: Calling cypress.run({ project: false }), cypress.run({ project: 'false' }), cypress.run({ project: 'true' }), or cypress.run({ project: '' }). Also when an unset shell variable is interpolated into a --project flag that is parsed and forwarded into the module API, or when options built for cypress.open() (where project:false means global mode) are reused for cypress.run().

Common situations: Reusing the same options object for both open and run; CI scripts that pass a conditional project flag that collapses to an empty string; tooling that sets project to a boolean flag instead of a path.

Related errors


AI-assisted analysis of cypress-io/cypress@0d85fdc912 (2026-08-12). Data as JSON: /api/errors/773eb2d9e1da996f. Report an issue: GitHub.