saadeghi/daisyui · error · Error

Could not start the browser: ${spawnError.message}

Error message

Could not start the browser: ${spawnError.message}

What it means

waitForDebuggingPort polls getSpawnError(); the browser child's 'error' event handler sets spawnError when Node itself fails to spawn the process (ENOENT, EACCES, EPERM). When detected during the wait loop, it throws wrapping the spawn error message.

Source

Thrown at packages/tailwind-play-share/index.mjs:265

    if (executable) return executable
  }

  throw new Error(
    "Chrome or Chromium was not found. Set TAILWIND_PLAY_BROWSER or pass --browser <path>.",
  )
}

const delay = (milliseconds) =>
  new Promise((resolvePromise) => setTimeout(resolvePromise, milliseconds))

async function waitForDebuggingPort(profileDirectory, browserProcess, timeoutMs, getSpawnError) {
  const activePortFile = join(profileDirectory, "DevToolsActivePort")
  const deadline = Date.now() + timeoutMs

  while (Date.now() < deadline) {
    const spawnError = getSpawnError()
    if (spawnError) {
      throw new Error(`Could not start the browser: ${spawnError.message}`)
    }
    if (browserProcess.exitCode !== null) {
      throw new Error(`Browser exited before starting (exit code ${browserProcess.exitCode})`)
    }

    try {
      const [portText] = (await readFile(activePortFile, "utf8")).trim().split(/\r?\n/)
      const port = Number(portText)
      if (Number.isInteger(port) && port > 0) return port
    } catch {
      // Chrome creates this file after its DevTools server is ready.
    }

    await delay(50)
  }

  throw new Error("Timed out while starting Chrome's DevTools server")
}

View on GitHub (pinned to 42b09e637e)

Solutions

  1. Re-check the executable: `ls -l` and try launching it manually.
  2. Fix permissions: `chmod +x` on the binary.
  3. Reinstall the browser or point --browser at a known-good binary.
  4. Note this error is re-thrown by launchBrowser with Chrome's stderr appended (see error 38).
Defensive patterns

Strategy: try-catch

Validate before calling

import { access, constants } from 'node:fs/promises'
async function canSpawn(p) {
  try { await access(p, constants.X_OK); return true } catch { return false }
}

Try / catch

try {
  return await launchBrowser(executable, opts)
} catch (error) {
  if (/Could not start the browser/.test(error.message)) {
    // re-resolve executable, fix perms, then retry once
  }
  throw error
}

Prevention

When it happens

Trigger: The executable path was readable at discovery time but cannot actually launch: file removed between checks (race), broken symlink, missing execute bit for the spawning user, or the OS cannot execute it.

Common situations: Stale symlink to a browser that was upgraded away; permissions changed by a package manager post-install; cross-architecture binary on the wrong CPU.

Related errors


AI-assisted analysis of saadeghi/daisyui@42b09e637e (2026-08-13). Data as JSON: /api/errors/e95e3a2e76d46371. Report an issue: GitHub.