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

  1. Register the daemon first: manager.register({ name, interval, enabled: true }, task) before start(name)
  2. Probe existence with manager.getState(name) and fail loudly at startup if expected daemons are missing
  3. 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

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


AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18). Data as JSON: /api/errors/4fdd412f96912b17. Report an issue: GitHub.