sipeed/picoclaw · error

cannot found model '%s' in config

Error message

cannot found model '%s' in config

What it means

picoclaw model <alias> accepts only aliases present in model_list with enabled: true, plus the built-in alias local-model (the local VLLM default). This error means the argument matched no enabled entry. Note the message itself is ungrammatical ('cannot found') — it simply reports the model was not found. The match against ModelName is exact and case-sensitive.

Source

Thrown at cmd/picoclaw/internal/model/command.go:113

		if !model.Enabled {
			continue
		}
		fmt.Printf("%s- %s (%s)\n", marker, model.ModelName, model.Model)
	}
}

func setDefaultModel(configPath string, cfg *config.Config, modelName string) error {
	// Validate that the model exists in model_list
	modelFound := false
	for _, model := range cfg.ModelList {
		if model.Enabled && model.ModelName == modelName {
			modelFound = true
			break
		}
	}

	if !modelFound && modelName != LocalModel {
		return fmt.Errorf("cannot found model '%s' in config", modelName)
	}

	// Update the default model
	// Clear old model field and set new model_name
	oldModel := cfg.Agents.Defaults.ModelName

	cfg.Agents.Defaults.ModelName = modelName

	// Save config back to file
	if err := config.SaveConfig(configPath, cfg); err != nil {
		return fmt.Errorf("failed to save config: %w", err)
	}

	fmt.Printf("✓ Default model changed from '%s' to '%s'\n",
		formatModelName(oldModel), modelName)
	fmt.Println("\nThe new default model will be used for all agent interactions.")

	return nil

View on GitHub (pinned to 49183d7e8d)

Solutions

  1. Open the config and use the exact model_name of an enabled model_list entry
  2. Re-enable the entry (enabled: true) or re-add it: picoclaw model add -n <alias>
  3. For the built-in local VLLM default, use picoclaw model local-model
  4. Remember the argument is the local alias, not the provider model id

Example fix

# before
$ picoclaw model gpt-4o
cannot found model 'gpt-4o' in config

# after — use the alias from model_list (or local-model)
$ picoclaw model custom-prefer
Defensive patterns

Strategy: validation

Validate before calling

func enabledModelNames(cfg *config.Config) []string {
  names := make([]string, 0, len(cfg.ModelList))
  for _, m := range cfg.ModelList {
    if m != nil && m.Enabled {
      names = append(names, m.ModelName)
    }
  }
  return names
}

if modelName != model.LocalModel && !slices.Contains(enabledModelNames(cfg), modelName) {
  return fmt.Errorf("model %q not found; enabled models: %v (or use local-model)", modelName, enabledModelNames(cfg))
}

Type guard

func isModelNotFoundError(err error) bool {
  return err != nil && strings.Contains(err.Error(), "in config") && strings.Contains(err.Error(), "model")
}

Try / catch

if err := setDefaultModel(configPath, cfg, name); err != nil {
  if isModelNotFoundError(err) {
    // show enabled model_name values and local-model, then re-ask for input
  }
  return err
}

Prevention

When it happens

Trigger: Typo or wrong case in the alias; the entry exists but has enabled: false; model_list is empty because the config was regenerated; the model was added under a different -n/--name alias (default custom-prefer); passing the provider model id (e.g. gpt-4o) instead of the local alias.

Common situations: Setting the default after models were re-added under new aliases; provider entries disabled during troubleshooting; users assuming the command takes the model id rather than the alias.

Related errors


AI-assisted analysis of sipeed/picoclaw@49183d7e8d (2026-08-15). Data as JSON: /api/errors/307db7297de5f2d7. Report an issue: GitHub.