charmbracelet/crush · error

failed to load config from paths %v: %w

Error message

failed to load config from paths %v: %w

What it means

Returned by config.Load when loadFromConfigPaths fails while reading/parsing the discovered config files (crushrc / crush.json) at the candidate paths. The message includes the exact list of paths attempted and the underlying parse or read error.

Source

Thrown at internal/config/load.go:49

	powernapConfig "github.com/charmbracelet/x/powernap/pkg/config"
	"github.com/qjebbs/go-jsons"
	"github.com/tidwall/gjson"
	"github.com/tidwall/sjson"
)

const defaultCatwalkURL = "https://catwalk.charm.land"

// Load loads the configuration from the default paths and returns a
// ConfigStore that owns both the pure-data Config and all runtime state.
func Load(workingDir, dataDir string, debug bool) (*ConfigStore, error) {
	// Migrate deprecated disable_notifications before loading config.
	migrateDisableNotifications()

	configPaths := lookupConfigs(workingDir)

	cfg, loadedPaths, err := loadFromConfigPaths(context.Background(), configPaths)
	if err != nil {
		return nil, fmt.Errorf("failed to load config from paths %v: %w", configPaths, err)
	}

	cfg.setDefaults(workingDir, dataDir)

	store := &ConfigStore{
		config:         cfg,
		workingDir:     workingDir,
		globalDataPath: GlobalConfigData(),
		workspacePath:  filepath.Join(cfg.Options.DataDirectory, fmt.Sprintf("%s.json", appName)),
		loadedPaths:    loadedPaths,
	}

	if debug {
		cfg.Options.Debug = true
	}

	// Load workspace config last so it has highest priority.
	if wsData, err := os.ReadFile(store.workspacePath); err == nil && len(wsData) > 0 {

View on GitHub (pinned to 7944b8e522)

Solutions

  1. Read the wrapped error for the specific file and line of the config mistake and fix the syntax/value.
  2. Validate the crushrc with bash -n or by sourcing it in a test shell to catch syntax errors.
  3. Check file permissions on the listed config paths.
  4. Migrate deprecated crush.json settings to crushrc if the JSON schema is the problem.
  5. Temporarily rename the config files to confirm they are the source of the failure.

Example fix

// before (crushrc)
provider anthropic {
  model claude
  missing_quote = "oops
}
// after
provider anthropic {
  model claude-sonnet-4-5
  api_key_env = ANTHROPIC_API_KEY
}
Defensive patterns

Strategy: validation

Validate before calling

// shellcheck-style pre-check of crushrc before launching
if out, err := exec.Command("bash", "-n", crushrcPath).CombinedOutput(); err != nil {
	return fmt.Errorf("invalid crushrc: %s", out)
}

Type guard

func isConfigLoadError(err error) bool {
	return err != nil && strings.Contains(err.Error(), "failed to load config from paths")
}

Try / catch

if err != nil && isConfigLoadError(err) {
	// the message lists offending paths; show them and the wrapped cause to the user
	return fmt.Errorf("fix your crush config: %w", err)
}

Prevention

When it happens

Trigger: Calling config.Get (or Load) when a crushrc/crush.json file in the working or home directory has a syntax error, uses unknown builtins, or cannot be read (permissions/I-O). configPaths in the message identify which files were involved.

Common situations: Hand-edited crushrc with a Bash syntax error; invalid values passed to builtins like provider/model/mcp; deprecated crush.json with schema mistakes; unreadable config file after permission changes.

Related errors


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