ruvnet/ruflo · error
Daemon '${name}' not found
Error message
Daemon '${name}' not found What it means
DaemonManager.start(name) throws when no daemon with that name was registered — the internal daemons Map lookup returns undefined. The manager has no auto-registration, so starting is only valid for names previously passed to register(). Note the ordering of checks in start(): an unknown name throws, a known-but-running daemon is a silent no-op, and a known-but-disabled daemon throws a different error.
Source
Thrown at v3/@claude-flow/hooks/src/daemons/index.ts:75
}
const state: DaemonState = {
name: config.name,
status: 'stopped',
executionCount: 0,
failureCount: 0,
};
this.daemons.set(config.name, { config, state, task });
}
/**
* Start a daemon
*/
async start(name: string): Promise<void> {
const daemon = this.daemons.get(name);
if (!daemon) {
throw new Error(`Daemon '${name}' not found`);
}
if (daemon.state.status === 'running') {
return; // Already running
}
if (!daemon.config.enabled) {
throw new Error(`Daemon '${name}' is disabled`);
}
daemon.state.status = 'starting';
daemon.state.startedAt = new Date();
try {
// Start interval timer
daemon.timer = setInterval(async () => {
await this.executeDaemonTask(name);
}, daemon.config.interval);View on GitHub (pinned to fa13ee4ad6)
Solutions
- Register the daemon first: manager.register({ name, interval, enabled: true }, task) before start(name)
- Probe existence with manager.getState(name) and fail loudly at startup if expected daemons are missing
- Define daemon names as shared constants used by both register and start to prevent drift
Example fix
// before
await manager.start('metrics'); // throws: never registered
// after
if (manager.getState('metrics') === undefined) {
manager.register({ name: 'metrics', interval: 60_000, enabled: true }, task);
}
await manager.start('metrics'); Defensive patterns
Strategy: validation
Validate before calling
function assertDaemon(manager: DaemonManager, name: string): void {
if (manager.getState(name) === undefined) {
throw new Error(`daemon '${name}' not registered; check registration order`);
}
}
assertDaemon(manager, 'metrics');
await manager.start('metrics'); Type guard
function isRegistered(manager: DaemonManager, name: string): name is string {
return manager.getState(name) !== undefined;
} Try / catch
try {
await manager.start(name);
} catch (e) {
if (e instanceof Error && e.message.includes('not found')) {
logger.error(`daemon '${name}' never registered — startup order bug`);
}
throw e;
} Prevention
- Run a startup assertion over the full expected daemon list before starting any of them
- Define daemon names as constants shared by register/start/stop sites
- Ensure registration code is unconditional before startAll()/start() in bootstrap
When it happens
Trigger: Calling await manager.start('metrics') when 'metrics' was never registered — typo in the name, registration code path not executed (conditional import, early return), or starting before the registration module ran.
Common situations: Name strings duplicated between registration and start sites drifting apart (renames); feature-gated registration while start is unconditional; race where start is invoked during bootstrap before registration completes.
Understand the failure class
Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.
Related errors
- Daemon '${config.name}' is already registered
- Daemon '${name}' is disabled
- Collection ${collectionId} not found
- Can only resume paused agent
- SSRF guard: invalid URL — ${rawUrl}
AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18).
Data as JSON: /api/errors/4fdd412f96912b17.
Report an issue: GitHub.