multica-ai/multica · error
parse CLI config: %w
Error message
parse CLI config: %w
What it means
The config file at the profile path was read successfully but json.Unmarshal could not decode it into CLIConfig. The wrapped error identifies the JSON syntax error and its byte offset. A missing file is treated as an empty config, so this only happens with present-but-invalid content.
Source
Thrown at server/internal/cli/config.go:306
return LoadCLIConfigForProfile("")
}
// LoadCLIConfigForProfile reads the CLI config for the given profile.
func LoadCLIConfigForProfile(profile string) (CLIConfig, error) {
path, err := CLIConfigPathForProfile(profile)
if err != nil {
return CLIConfig{}, err
}
data, err := os.ReadFile(path)
if err != nil {
if errors.Is(err, os.ErrNotExist) {
return CLIConfig{}, nil
}
return CLIConfig{}, fmt.Errorf("read CLI config: %w", err)
}
var cfg CLIConfig
if err := json.Unmarshal(data, &cfg); err != nil {
return CLIConfig{}, fmt.Errorf("parse CLI config: %w", err)
}
return cfg, nil
}
// SaveCLIConfig writes the CLI config to disk atomically (default profile).
func SaveCLIConfig(cfg CLIConfig) error {
return SaveCLIConfigForProfile(cfg, "")
}
// SaveCLIConfigForProfile writes the CLI config for the given profile.
func SaveCLIConfigForProfile(cfg CLIConfig, profile string) error {
path, err := CLIConfigPathForProfile(profile)
if err != nil {
return err
}
dir := filepath.Dir(path)
dirMode := os.FileMode(0o755)
if strings.TrimSpace(os.Getenv(TaskConfigRootEnv)) != "" {View on GitHub (pinned to 2c0912b6ec)
Solutions
- Open the file named in the path resolution and fix the JSON syntax error indicated by the offset in the wrapped message
- If the file is corrupt beyond repair, delete or rename it — the loader treats a missing file as a fresh empty config
- Re-save a known-good config via the CLI's own config set/save command so future writes are atomic
- If a field type changed after an upgrade, rewrite the values to match the current schema or start from the empty config
Example fix
// before: ~/.multica/profiles/dev/config.json
{"default_workspace": "acme",}
// after
{"default_workspace": "acme"} Defensive patterns
Strategy: validation
Validate before calling
data, err := os.ReadFile(path)
if err == nil {
if !json.Valid(data) {
// quarantine the bad file and start from an empty config
os.Rename(path, path+".invalid")
}
} Type guard
func isConfigParseErr(err error) bool {
var syn *json.SyntaxTypeError
return err != nil && (strings.Contains(err.Error(), "parse CLI config:") || errors.As(err, &syn))
} Try / catch
cfg, err := cli.LoadCLIConfigForProfile(profile)
if err != nil {
var synErr *json.SyntaxError
if errors.As(err, &synErr) {
// offer to reset the config: delete the file so the next load is empty
}
return err
} Prevention
- Modify config only through the CLI's own set/save commands, which write atomically
- Validate hand-edited JSON with jq before saving
- Back up config.json before schema-changing upgrades
When it happens
Trigger: Calling LoadCLIConfig()/LoadCLIConfigForProfile when config.json contains truncated JSON (a crashed atomic write), hand-edited JSON with a trailing comma, or an object whose fields changed type between CLI versions.
Common situations: Editing ~/.multica/config.json by hand and introducing a syntax error; a killed process leaving a partially written file despite the temp-file rename; schema drift after upgrading the CLI to a version with different field types.
Related errors
- parse response: %w
- Invalid desktop runtime config: ${field} must be a non-empty
- mint PAT: target API URL not set
- runtime local skill discovery failed
- body must be a JSON object or array
AI-assisted analysis of multica-ai/multica@2c0912b6ec (2026-08-15).
Data as JSON: /api/errors/2f84b584748d285b.
Report an issue: GitHub.