{"record":{"id":"bef60b52ba0a896a","repo":"withastro/astro","slug":"another-astro-dev-server-is-already-running-ur","errorCode":null,"errorMessage":"Another astro dev server is already running.\n\n  URL:  ${existingServer.url}\n  PID:  ${existingServer.pid}\n\nRun `astro dev stop` to stop it, or use `astro dev --force` to replace it.","messagePattern":"Another astro dev server is already running\\.\n\n  URL:  (.+?)\n  PID:  (.+?)\n\nRun `astro dev stop` to stop it, or use `astro dev --force` to replace it\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/astro/src/cli/dev/index.ts","lineNumber":221,"sourceCode":"\t\tconst inlineConfig = flagsToAstroInlineConfig(flags);\n\t\treturn await devServer(inlineConfig);\n\t}\n\n\tconst existingServer = await checkExistingServer(root);\n\tif (existingServer) {\n\t\tif (flags.force) {\n\t\t\t// --force: kill the existing server and replace it\n\t\t\tawait killDevServer(root, existingServer);\n\t\t} else {\n\t\t\tconst message = [\n\t\t\t\t'Another astro dev server is already running.',\n\t\t\t\t'',\n\t\t\t\t`  URL:  ${existingServer.url}`,\n\t\t\t\t`  PID:  ${existingServer.pid}`,\n\t\t\t\t'',\n\t\t\t\t`Run \\`astro dev stop\\` to stop it, or use \\`astro dev --force\\` to replace it.`,\n\t\t\t].join('\\n');\n\t\t\tthrow new Error(message);\n\t\t}\n\t}\n\n\tconst inlineConfig = flagsToAstroInlineConfig(flags);\n\tconst server = await devServer(inlineConfig);\n\n\t// Use Vite's resolved URL which accounts for host and protocol (http/https).\n\tconst serverUrl = resolveLockFileUrl(server.resolvedUrls);\n\tif (serverUrl) {\n\t\twriteLockFile(root, {\n\t\t\tpid: process.pid,\n\t\t\tport: server.address.port,\n\t\t\turl: serverUrl,\n\t\t\turls: server.resolvedUrls,\n\t\t\tbackground: !!process.env.ASTRO_DEV_BACKGROUND,\n\t\t\tstartedAt: new Date().toISOString(),\n\t\t});\n","sourceCodeStart":203,"sourceCodeEnd":239,"githubUrl":"https://github.com/withastro/astro/blob/52e6c34790cc8ac4e69e6135ace06049867e5c4a/packages/astro/src/cli/dev/index.ts#L203-L239","documentation":"Before starting, `astro dev` reads the project's lock file (`.astro/dev.json` under the project root) and checks the recorded PID. A live dev server is already registered for this root; starting a second one would make `astro dev stop`/`status`/`logs` unreliable, so the command aborts unless `--force` is passed (which kills and replaces the existing server).","triggerScenarios":"Running `astro dev` while a previous dev server for the same project root is still alive — another terminal, a detached/background server, a CI step, or a server spawned by an AI coding agent via `astro dev --background`.","commonSituations":"Forgotten server in another terminal or editor task; background server started by tooling that keeps running after the work session; shared machine/checkout where a teammate's server holds the lock.","solutions":["Run `astro dev stop` to stop the existing server, then start again","Or replace it in one step: `astro dev --force`","If the message persists unexpectedly, inspect `.astro/dev.json` in the project root — a PID reused by another process can fake a live server; delete the file or use `--force`"],"exampleFix":"# before\nastro dev   # Another astro dev server is already running. URL: ... PID: ...\n\n# after\nastro dev stop\nastro dev\n# or replace directly:\nastro dev --force","handlingStrategy":"validation","validationCode":"import { existsSync, readFileSync } from 'node:fs';\nimport { join } from 'node:path';\n\n// true when a live dev server holds the lock for this project root\nfunction devServerIsRunning(root) {\n  const lock = join(root, '.astro', 'dev.json');\n  if (!existsSync(lock)) return false;\n  try {\n    const { pid } = JSON.parse(readFileSync(lock, 'utf8'));\n    process.kill(pid, 0); // throws if the PID is gone\n    return true;\n  } catch {\n    return false; // stale lock — safe to start\n  }\n}\n\nif (devServerIsRunning(root)) {\n  // run `astro dev stop` (or pass --force) before `astro dev`\n}","typeGuard":null,"tryCatchPattern":"import { spawnSync } from 'node:child_process';\nconst r = spawnSync('astro', ['dev'], { encoding: 'utf8' });\nif (r.status !== 0 && /Another astro dev server is already running/.test(r.stderr)) {\n  spawnSync('astro', ['dev', 'stop'], { stdio: 'inherit' });\n  // retry `astro dev` once\n}","preventionTips":["End dev sessions with `astro dev stop` (or Ctrl-C) so the lock file is cleaned up","In scripts, run `astro dev --force` when the previous server's lifetime is owned by the same script","Remember the lock is per project root — check other terminals, editor tasks, and agent-spawned background servers for the same checkout"],"tags":["cli","astro-dev","lock-file","process-management"],"backgroundTag":"dev-server-already-running","analyzedSha":"52e6c34790cc8ac4e69e6135ace06049867e5c4a","analyzedAt":"2026-08-18T18:48:03.901Z","contentChangedAt":"2026-08-18T18:48:03.901Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}