charmbracelet/crush · critical

failed to load configuration: %v

Error message

failed to load configuration: %v

What it means

The server command calls config.Load(config.GlobalWorkspaceDir(), dataDir, debug) to read and validate crushrc/crush.json. Any load or validation failure — malformed config syntax, unknown keys, invalid provider/agent definitions, unreadable files — is wrapped as "failed to load configuration".

Source

Thrown at internal/cmd/server.go:42

	rootCmd.AddCommand(serverCmd)
}

var serverCmd = &cobra.Command{
	Use:   "server",
	Short: "Start the Crush server",
	RunE: func(cmd *cobra.Command, _ []string) error {
		dataDir, err := cmd.Flags().GetString("data-dir")
		if err != nil {
			return fmt.Errorf("failed to get data directory: %v", err)
		}
		debug, err := cmd.Flags().GetBool("debug")
		if err != nil {
			return fmt.Errorf("failed to get debug flag: %v", err)
		}

		cfg, err := config.Load(config.GlobalWorkspaceDir(), dataDir, debug)
		if err != nil {
			return fmt.Errorf("failed to load configuration: %v", err)
		}

		hostURL, err := server.ParseHostURL(serverHost)
		if err != nil {
			return fmt.Errorf("invalid server host: %v", err)
		}

		logFile := filepath.Join(config.GlobalCacheDir(), "server-"+safeHostName(hostURL), "crush.log")

		if term.IsTerminal(os.Stderr.Fd()) {
			crushlog.Setup(logFile, debug, os.Stderr)
		} else {
			crushlog.Setup(logFile, debug)
		}

		srv := server.NewServer(cfg, hostURL.Scheme, hostURL.Host)
		srv.SetLogger(slog.Default())
		slog.Info("Starting Crush server...", "addr", serverHost)

View on GitHub (pinned to 7944b8e522)

Solutions

  1. Read the wrapped inner error in the message — it names the exact file and validation problem.
  2. Run `crush schema` output or docs to check your crushrc/crush.json against the expected config structure.
  3. Temporarily rename crush.json/crushrc and start the server with defaults to isolate the offending file.
  4. Fix bash syntax errors by sourcing the crushrc in bash (`bash -n` for a syntax check).
  5. Verify HOME/XDG paths so GlobalWorkspaceDir() points at the directory holding your intended config.

Example fix

// before (crushrc)
provider anthropic {
  modl "claude-sonnet-4"   # typo: unknown key
}
// after
provider anthropic {
  model "claude-sonnet-4"
}
Defensive patterns

Strategy: validation

Validate before calling

// syntax-check crushrc and JSON validity before starting the server
bash -n ~/.config/crush/crushrc && jq empty ~/.config/crush/crush.json 2>/dev/null || echo "fix config errors first"

Try / catch

cfg, err := config.Load(config.GlobalWorkspaceDir(), dataDir, debug)
if err != nil {
    return fmt.Errorf("failed to load configuration: %v", err) // read the wrapped cause for file/line
}

Prevention

When it happens

Trigger: Starting `crush server` with a syntactically invalid crushrc (bash syntax error, unknown builtin arguments), a crush.json failing schema validation, or a config file that cannot be read at GlobalWorkspaceDir()/data-dir.

Common situations: Hand-edited crushrc with a typo in a `provider`/`model`/`mcp` builtin; JSON config left in a half-edited state; API keys referenced via env vars that are unset at server start; permissions referencing nonexistent tools.

Related errors


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