sipeed/picoclaw · error
turn_profile.%s.mode custom is not supported in this version
Error message
turn_profile.%s.mode custom is not supported in this version
What it means
Returned by validateTurnProfileBlock when a turn_profile block's effective mode is `custom` but that block does not allow custom profiles in this build. In the current code only `skills` and `tools` blocks pass allowCustom=true; `history` and `system_prompt` pass false, so `mode: custom` under turn_profile.history or turn_profile.system_prompt is rejected even though the custom mode exists elsewhere.
Source
Thrown at pkg/config/turn_profile.go:109
if err := validateTurnProfileBlock("skills", profile.Skills, true); err != nil {
return err
}
if err := validateTurnProfileBlock("tools", profile.Tools, true); err != nil {
return err
}
return nil
}
func validateTurnProfileBlock(field string, block TurnProfileBlock, allowCustom bool) error {
mode := block.Mode.Effective()
switch mode {
case TurnProfileModeDefault, TurnProfileModeOff:
return nil
case TurnProfileModeCustom:
if allowCustom {
return nil
}
return fmt.Errorf("turn_profile.%s.mode custom is not supported in this version", field)
default:
return fmt.Errorf("turn_profile.%s.mode has unsupported mode %q", field, block.Mode)
}
}
func cleanStringList(values []string) []string {
if len(values) == 0 {
return nil
}
out := make([]string, 0, len(values))
seen := make(map[string]struct{}, len(values))
for _, value := range values {
value = strings.TrimSpace(value)
if value == "" {
continue
}
if _, ok := seen[value]; ok {
continueView on GitHub (pinned to 49183d7e8d)
Solutions
- Remove `mode: custom` from the history/system_prompt block (let it default) or set an allowed mode
- Move the customization you wanted into a block that supports custom (skills, tools)
- Upgrade or check release notes if custom history/system_prompt is expected to be supported in a newer build
- Re-validate the config after the change
Example fix
# before
turn_profile:
history:
mode: custom
# after
turn_profile:
history:
mode: default Defensive patterns
Strategy: validation
Validate before calling
// Reject custom mode for blocks that don't allow it, pre-load.
var customForbidden = map[string]bool{"history": true, "system_prompt": true}
func turnProfileModesOK(p TurnProfile) error {
if customForbidden["history"] && p.History.Mode.Effective() == TurnProfileModeCustom {
return fmt.Errorf("turn_profile.history: custom not supported")
}
if customForbidden["system_prompt"] && p.SystemPrompt.Mode.Effective() == TurnProfileModeCustom {
return fmt.Errorf("turn_profile.system_prompt: custom not supported")
}
return nil
} Type guard
func allowsCustom(block string) bool {
switch block {
case "skills", "tools":
return true // allowCustom=true at call sites
default: // history, system_prompt
return false
}
} Try / catch
if err := cfg.Validate(); err != nil {
if strings.Contains(err.Error(), "custom is not supported") {
// strip mode: custom from history/system_prompt and retry
}
return err
} Prevention
- Check which blocks accept custom in current docs before writing custom profiles
- Keep custom profiles under skills/tools only
- On version bumps, re-validate config and remove newly-gated modes
When it happens
Trigger: Config contains `turn_profile:\n history:\n mode: custom` or `turn_profile:\n system_prompt:\n mode: custom`. Block.Mode.Effective() resolves to TurnProfileModeCustom, allowCustom is false for those two blocks, and the error fires naming the field.
Common situations: Copying a skills/tools-style custom profile into history or system_prompt, or upgrading to a version where custom is gated per-block. Users assume `custom` is universally available because other blocks accept it.
Related errors
- turn_profile.%s.mode has unsupported mode %q
- invalid WeCom QR generate URL: %w
- invalid WeCom QR query URL: %w
- invalid WeCom QR page URL: %w
- api key is required
AI-assisted analysis of sipeed/picoclaw@49183d7e8d (2026-08-15).
Data as JSON: /api/errors/ac26b5166e80aff4.
Report an issue: GitHub.