charmbracelet/crush · error

agent configuration not found

Error message

agent configuration not found

What it means

Thrown when config exists but cfg.Agents has no entry for config.AgentCoder. The toggle-thinking flow requires the default 'coder' agent to be defined; a config that omits or renames it cannot resolve which model to flip thinking on.

Source

Thrown at internal/ui/model/ui.go:1991

		m.dialog.CloseDialog(dialog.CommandsID)
	case dialog.ActionToggleCompactMode:
		cmds = append(cmds, m.toggleCompactMode())
		m.dialog.CloseDialog(dialog.CommandsID)
	case dialog.ActionTogglePills:
		if cmd := m.togglePillsExpanded(); cmd != nil {
			cmds = append(cmds, cmd)
		}
		m.dialog.CloseDialog(dialog.CommandsID)
	case dialog.ActionToggleThinking:
		cmds = append(cmds, m.updateAgentModelCmd(func() tea.Msg {
			cfg := m.com.Config()
			if cfg == nil {
				return util.ReportError(errors.New("configuration not found"))()
			}

			agentCfg, ok := cfg.Agents[config.AgentCoder]
			if !ok {
				return util.ReportError(errors.New("agent configuration not found"))()
			}

			currentModel := cfg.Models[agentCfg.Model]
			currentModel.Think = !currentModel.Think
			if err := m.com.Workspace.UpdatePreferredModel(config.ScopeGlobal, agentCfg.Model, currentModel); err != nil {
				return util.ReportError(err)()
			}
			m.com.Workspace.UpdateAgentModel(context.TODO())
			status := "disabled"
			if currentModel.Think {
				status = "enabled"
			}
			return util.NewInfoMsg("Thinking mode " + status)
		}))
		m.dialog.CloseDialog(dialog.CommandsID)
	case dialog.ActionToggleTransparentBackground:
		cmds = append(cmds, func() tea.Msg {
			cfg := m.com.Config()

View on GitHub (pinned to 7944b8e522)

Solutions

  1. Add back the default 'coder' agent definition to your config
  2. Run config validation (crush doctor / startup validation) to catch missing required agents
  3. Update the config to the current schema if it was written by an older Crush version

Example fix

// before (agents without coder)
[agents.task]
model = "anthropic/claude-sonnet-4"
// after
[agents.coder]
model = "anthropic/claude-sonnet-4"
[agents.task]
model = "anthropic/claude-sonnet-4"
Defensive patterns

Strategy: validation

Validate before calling

cfg := m.com.Config()
if cfg == nil || cfg.Agents == nil {
	return // cannot toggle thinking
}
if _, ok := cfg.Agents[config.AgentCoder]; !ok {
	return // coder agent missing
}

Type guard

func coderAgent(cfg *config.Config) (config.AgentConfig, bool) {
	a, ok := cfg.Agents[config.AgentCoder]
	return a, ok
}

Try / catch

agentCfg, ok := cfg.Agents[config.AgentCoder]
if !ok {
	return util.ReportError(fmt.Errorf("toggle thinking: agent %q not configured", config.AgentCoder))()
}

Prevention

When it happens

Trigger: Executing ActionToggleThinking with a config whose Agents map lacks the 'coder' key — e.g. a user-defined agents block that only defines a 'task' agent, or a typo'd/overridden agent name in crushrc.

Common situations: Hand-edited crushrc/crush.json that removed the coder agent; older config versions migrated without the default agent; partial config merges dropping the agent definition.

Related errors


AI-assisted analysis of charmbracelet/crush@7944b8e522 (2026-08-29). Data as JSON: /api/errors/5bf368dde94b5ee8. Report an issue: GitHub.