{"record":{"id":"98234d2f50872e0f","repo":"withastro/astro","slug":"another-astro-preview-server-is-already-running","errorCode":null,"errorMessage":"Another astro preview server is already running.\n\n  URL:  ${existingServer.url}\n  PID:  ${existingServer.pid}\n\nRun `astro preview stop` to stop it, or use `astro preview --force` to replace it.","messagePattern":"Another astro preview server is already running\\.\n\n  URL:  (.+?)\n  PID:  (.+?)\n\nRun `astro preview stop` to stop it, or use `astro preview --force` to replace it\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/astro/src/cli/preview/index.ts","lineNumber":93,"sourceCode":"\t\tlogger.error(\n\t\t\t'SKIP_FORMAT',\n\t\t\t`Unknown command: astro preview ${subcommand}\\n\\nRun \\`astro preview --help\\` to see available commands.`,\n\t\t);\n\t\tprocess.exit(1);\n\t}\n\n\tconst root = pathToFileURL(resolveRoot(flags.root) + '/');\n\tconst existingServer = checkExistingServer(root, 'preview');\n\tif (existingServer) {\n\t\tconst message = [\n\t\t\t'Another astro preview server is already running.',\n\t\t\t'',\n\t\t\t`  URL:  ${existingServer.url}`,\n\t\t\t`  PID:  ${existingServer.pid}`,\n\t\t\t'',\n\t\t\t`Run \\`astro preview stop\\` to stop it, or use \\`astro preview --force\\` to replace it.`,\n\t\t].join('\\n');\n\t\tthrow new Error(message);\n\t}\n\n\tconst inlineConfig = flagsToAstroInlineConfig(flags);\n\tconst server = await previewServer(inlineConfig);\n\tconst serverUrl = server.urls?.local[0]\n\t\t? new URL(server.urls.local[0]).origin\n\t\t: `http://${server.host ?? 'localhost'}:${server.port}`;\n\n\twriteLockFile(\n\t\troot,\n\t\t{\n\t\t\tpid: process.pid,\n\t\t\tport: server.port,\n\t\t\turl: serverUrl,\n\t\t\turls: server.urls,\n\t\t\tbackground: !!process.env.ASTRO_PREVIEW_BACKGROUND,\n\t\t\tstartedAt: new Date().toISOString(),\n\t\t},","sourceCodeStart":75,"sourceCodeEnd":111,"githubUrl":"https://github.com/withastro/astro/blob/d081033d5fe8e8a68c4bbbad4af9d2deb9c74bca/packages/astro/src/cli/preview/index.ts#L75-L111","documentation":"`astro preview` uses the same lock-file mechanism as `astro dev` but keyed to the `'preview'` role. Before binding it checks `checkExistingServer(root, 'preview')` and refuses to start a second preview server against the same project root. `--force` is supported to kill and replace the prior preview process.","triggerScenarios":"Running `astro preview` while a prior `astro preview` for the same root still holds the lock (live PID). Distinct from the dev server lock — a running `astro dev` does not trigger this, only another preview does.","commonSituations":"A preview server left running after building and starting it in another terminal; CI caching a workspace with a stale preview process; switching between multiple builds and forgetting the previous preview is still serving the old `dist/`.","solutions":["Run `astro preview stop` to stop the existing preview server.","Run `astro preview --force` to replace it in one command.","Manually kill the recorded PID and remove the preview lock file in `.astro/` if the process is already dead but the lock is stale.","Verify with `ps -p <PID>` before killing anything."],"exampleFix":"// before\n$ astro preview\n// after\n$ astro preview --force","handlingStrategy":"validation","validationCode":"function isPreviewServerRunning(root) {\n  const lockPath = join(root, '.astro', 'preview.lock');\n  if (!existsSync(lockPath)) return null;\n  try {\n    const { pid, url } = JSON.parse(readFileSync(lockPath, 'utf-8'));\n    if (pid && process.kill(pid, 0)) return { pid, url };\n  } catch {}\n  return null;\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Stop preview servers with `astro preview stop` before restarting.","Use `astro preview --force` in automated build/preview pipelines."],"tags":["cli","preview-server","lock-file","concurrency"],"backgroundTag":null,"analyzedSha":"d081033d5fe8e8a68c4bbbad4af9d2deb9c74bca","analyzedAt":"2026-08-12T13:37:29.035Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}