slopus/happy · error · Error

Unknown agent: ${id}. Available agents: ${available}

Error message

Unknown agent: ${id}. Available agents: ${available}

What it means

AgentRegistry.create looks up a factory by agent id in its factories map. An unregistered id means the requested agent type was never registered (or the id is misspelled), so it throws listing all available agent ids. This is the guard against instantiating unknown agent backends.

Source

Thrown at packages/happy-cli/src/agent/core/AgentRegistry.ts:81

   * @returns Array of registered agent IDs
   */
  list(): AgentId[] {
    return Array.from(this.factories.keys());
  }

  /**
   * Create an agent backend instance.
   * 
   * @param id - The agent identifier
   * @param opts - Options for creating the backend
   * @returns The created agent backend
   * @throws Error if the agent type is not registered
   */
  create(id: AgentId, opts: AgentFactoryOptions): AgentBackend {
    const factory = this.factories.get(id);
    if (!factory) {
      const available = this.list().join(', ') || 'none';
      throw new Error(`Unknown agent: ${id}. Available agents: ${available}`);
    }
    return factory(opts);
  }
}

/** Global agent registry instance */
export const agentRegistry = new AgentRegistry();

View on GitHub (pinned to b824cd0a46)

Solutions

  1. Use one of the ids listed in the error's 'Available agents' output.
  2. Ensure the module registering the agent factory is imported before create() is called.
  3. Fix the id spelling/casing to match the registered AgentId.
  4. If the agent was removed in an upgrade, migrate your config to the new id.

Example fix

// before
registry.create('claudeCode', opts); // typo, not registered
// after
registry.create('claude-code', opts);
Defensive patterns

Strategy: validation

Validate before calling

const available = agentRegistry.list();
if (!available.includes(agentId)) {
  throw new Error(`Agent '${agentId}' not registered. Available: ${available.join(', ')}`);
}
const agent = agentRegistry.create(agentId, opts);

Type guard

function isRegisteredAgent(id: string, registry: AgentRegistry): id is AgentId {
  return registry.list().includes(id as AgentId);
}

Try / catch

try {
  return agentRegistry.create(id, opts);
} catch (err) {
  if (err instanceof Error && err.message.startsWith('Unknown agent:')) {
    console.error(`${err.message}\nCheck your config agent name and that the agent module is imported.`);
  } else throw err;
}

Prevention

When it happens

Trigger: Passing an AgentId not passed to registry.register() in this process; a typo or casing mismatch in the id; calling create before the module that registers the agent was imported; a version change that renamed the agent id.

Common situations: Config file referencing an agent name removed/renamed in a CLI upgrade; plugin/module import order leaving the registry empty; using `acp` style inline commands where only a generic factory is expected but wasn't registered.

Related errors


AI-assisted analysis of slopus/happy@b824cd0a46 (2026-08-31). Data as JSON: /api/errors/059b88362f1bc74c. Report an issue: GitHub.