withastro/astro · error · Error
Another astro dev server is already running. URL
Error message
Another astro dev server is already running.
URL: ${existingServer.url}
PID: ${existingServer.pid}
Run `astro dev stop` to stop it, or use `astro dev --force` to replace it. What it means
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).
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`
Example fix
# before astro dev # Another astro dev server is already running. URL: ... PID: ... # after astro dev stop astro dev # or replace directly: astro dev --force
Defensive patterns
Strategy: validation
Validate before calling
import { existsSync, readFileSync } from 'node:fs';
import { join } from 'node:path';
// true when a live dev server holds the lock for this project root
function devServerIsRunning(root) {
const lock = join(root, '.astro', 'dev.json');
if (!existsSync(lock)) return false;
try {
const { pid } = JSON.parse(readFileSync(lock, 'utf8'));
process.kill(pid, 0); // throws if the PID is gone
return true;
} catch {
return false; // stale lock — safe to start
}
}
if (devServerIsRunning(root)) {
// run `astro dev stop` (or pass --force) before `astro dev`
} Try / catch
import { spawnSync } from 'node:child_process';
const r = spawnSync('astro', ['dev'], { encoding: 'utf8' });
if (r.status !== 0 && /Another astro dev server is already running/.test(r.stderr)) {
spawnSync('astro', ['dev', 'stop'], { stdio: 'inherit' });
// retry `astro dev` once
} Prevention
- 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
When it happens
Trigger: 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`.
Common situations: 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.
Related errors
- Another astro preview server is already running. URL
- `--ignore-lock` cannot be used together with
- Be sure to follow the
- ConfigNotFound
- Couldn't parse tsconfig.json or jsconfig.json
AI-assisted analysis of withastro/astro@52e6c34790 (2026-08-18).
Data as JSON: /api/errors/bef60b52ba0a896a.
Report an issue: GitHub.
Appendix: source
Thrown at packages/astro/src/cli/dev/index.ts:221
const inlineConfig = flagsToAstroInlineConfig(flags);
return await devServer(inlineConfig);
}
const existingServer = await checkExistingServer(root);
if (existingServer) {
if (flags.force) {
// --force: kill the existing server and replace it
await killDevServer(root, existingServer);
} else {
const message = [
'Another astro dev server is already running.',
'',
` URL: ${existingServer.url}`,
` PID: ${existingServer.pid}`,
'',
`Run \`astro dev stop\` to stop it, or use \`astro dev --force\` to replace it.`,
].join('\n');
throw new Error(message);
}
}
const inlineConfig = flagsToAstroInlineConfig(flags);
const server = await devServer(inlineConfig);
// Use Vite's resolved URL which accounts for host and protocol (http/https).
const serverUrl = resolveLockFileUrl(server.resolvedUrls);
if (serverUrl) {
writeLockFile(root, {
pid: process.pid,
port: server.address.port,
url: serverUrl,
urls: server.resolvedUrls,
background: !!process.env.ASTRO_DEV_BACKGROUND,
startedAt: new Date().toISOString(),
});
View on GitHub (pinned to 52e6c34790)