angular/angular-cli · error · Error
Port ${input.port} is unavailable. Try calling this tool aga
Error message
Port ${input.port} is unavailable. Try calling this tool again without the 'port' parameter to auto-assign a free port. What it means
The devserver_start tool checks the requested port via context.host.isPortAvailable before binding. If the port is already in use (or otherwise unavailable), it throws and suggests omitting the port parameter so the tool auto-assigns a free one.
Source
Thrown at packages/angular/cli/src/commands/mcp/tools/devserver/devserver-start.ts:67
workspacePathInput: input.workspace,
projectNameInput: input.project,
mcpWorkspace: context.workspace,
});
const key = getDevserverKey(workspacePath, projectName);
let devserver = context.devservers.get(key);
if (devserver) {
return createStructuredContentOutput({
message: `Development server for project '${projectName}' is already running.`,
address: localhostAddress(devserver.port),
});
}
let port: number;
if (input.port) {
if (!(await context.host.isPortAvailable(input.port))) {
throw new Error(
`Port ${input.port} is unavailable. Try calling this tool again without the 'port' parameter to auto-assign a free port.`,
);
}
port = input.port;
} else {
port = await context.host.getAvailablePort();
}
devserver = new LocalDevserver({
host: context.host,
project: projectName,
port,
workspacePath,
});
devserver.start();
context.devservers.set(key, devserver);
View on GitHub (pinned to bb72145f9a)
Solutions
- Call the tool again without the 'port' parameter so a free port is auto-assigned.
- Stop the process occupying the port (lsof -i :<port> / netstat to identify it, then kill it).
- Choose a different, higher, unprivileged port (e.g. 49152+).
- Shut down previously started dev servers via the devserver stop tool before restarting.
Example fix
// before
devserver_start({ port: 4200 });
// after
devserver_start({}); // port auto-assigned
Defensive patterns
Strategy: retry
Validate before calling
import { createServer } from 'node:net';
function isPortFree(port: number): Promise<boolean> {
return new Promise((res) => {
const srv = createServer();
srv.once('error', () => res(false));
srv.once('listening', () => srv.close(() => res(true)));
srv.listen(port);
});
}
if (!(await isPortFree(4200))) console.warn('port 4200 busy — omit port param'); Try / catch
try {
await devserver_start({ port: 4200 });
} catch (e) {
if ((e as Error).message.includes('is unavailable')) {
await devserver_start({}); // auto-assign free port
} else throw e;
} Prevention
- Omit the 'port' parameter unless a fixed port is truly required
- Check for lingering dev server processes before restarting on the same port
- Use distinct fixed ports per project to avoid collisions
- Prefer unprivileged ports (>1024)
When it happens
Trigger: Calling devserver_start with input.port set to a port already occupied by another process, or a port below 1024 without privileges, or raced by another service binding between check and bind.
Common situations: A previous dev server still running on 4200; another app (Docker, other dev server) holding the port; re-running the tool after a previous session that didn't shut down; reusing a hardcoded port across projects.
Related errors
- Unable to load package information from registry: ${e.messag
- Unable to load package information from registry.
- Search request failed with status ${response.status} (${resp
- ${parsedError.summary}
- Package ${name} was not found on the registry. Skipping.
AI-assisted analysis of angular/angular-cli@bb72145f9a (2026-08-30).
Data as JSON: /api/errors/0093cd0f232e670b.
Report an issue: GitHub.