ruvnet/ruflo · error · Error
Transport "${name}" already exists
Error message
Transport "${name}" already exists What it means
TransportManager stores transports in a Map keyed by a caller-chosen name; addTransport(name, transport) throws if the name is already registered, preventing silent replacement of a live transport. Names are arbitrary strings with no built-in namespacing, so collisions are purely a caller-side naming problem.
Source
Thrown at v3/@claude-flow/mcp/src/transport/index.ts:112
connections: 1,
},
};
}
}
export function createInProcessTransport(logger: ILogger): ITransport {
return new InProcessTransport(logger);
}
export class TransportManager {
private transports: Map<string, ITransport> = new Map();
private running = false;
constructor(private readonly logger: ILogger) {}
addTransport(name: string, transport: ITransport): void {
if (this.transports.has(name)) {
throw new Error(`Transport "${name}" already exists`);
}
this.transports.set(name, transport);
this.logger.debug('Transport added', { name, type: transport.type });
}
async removeTransport(name: string): Promise<boolean> {
const transport = this.transports.get(name);
if (!transport) {
return false;
}
await transport.stop();
this.transports.delete(name);
this.logger.debug('Transport removed', { name });
return true;
}
getTransport(name: string): ITransport | undefined {View on GitHub (pinned to fa13ee4ad6)
Solutions
- Check manager.getTransport(name) (or getTransportNames()) first and skip if present
- Await manager.removeTransport(name) first when deliberately replacing a transport
- Derive names from the transport type or a unique id per registration site
Example fix
// before
manager.addTransport('http', httpTransport);
// after
if (!manager.getTransport('http')) {
manager.addTransport('http', httpTransport);
} else {
await manager.removeTransport('http');
manager.addTransport('http', httpTransport);
} Defensive patterns
Strategy: validation
Validate before calling
if (manager.getTransport(name)) {
await manager.removeTransport(name); // deliberate replacement
}
manager.addTransport(name, transport); Try / catch
try {
manager.addTransport(name, transport);
} catch (e) {
if (e instanceof Error && e.message.includes('already exists')) {
// double init - skip or replace via removeTransport first
} else {
throw e;
}
} Prevention
- Check getTransport(name) before addTransport
- Use unique names per registration site (e.g. `${subsystem}:${type}`)
- Make init routines idempotent so re-running them cannot double-register
When it happens
Trigger: Registering 'http' twice (a default registration plus a custom one); an init routine that re-runs on hot reload without constructing a new TransportManager; two subsystems both registering under a generic name like 'main' or 'default'.
Common situations: Framework boilerplate and user code both registering a transport; retrying an initialization sequence that already succeeded; name generation from env/counters repeating across modules.
Related errors
- HTTP transport already running
- TransportManager already running
- Stdio transport already running
- WebSocket transport already running
- HTTP transport already running
AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18).
Data as JSON: /api/errors/346b2c658c1a74fb.
Report an issue: GitHub.