{"record":{"id":"00460b88f8bd9e90","repo":"larksuite/cli","slug":"errmalformedconfig","errorCode":"ErrMalformedConfig","errorMessage":"invalid config format: %w: %w","messagePattern":"invalid config format: %w: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"internal/core/config.go","lineNumber":231,"sourceCode":"\treturn filepath.Join(GetConfigDir(), \"config.json\")\n}\n\n// ErrMalformedConfig marks a config-load failure caused by malformed file\n// content (unparseable JSON, structurally empty) rather than a missing or\n// unreadable file. Callers classify with errors.Is rather than sniffing the\n// message text.\nvar ErrMalformedConfig = errors.New(\"malformed config\")\n\n// LoadMultiAppConfig loads multi-app config from disk.\nfunc LoadMultiAppConfig() (*MultiAppConfig, error) {\n\tdata, err := vfs.ReadFile(GetConfigPath())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar multi MultiAppConfig\n\tif err := json.Unmarshal(data, &multi); err != nil {\n\t\treturn nil, fmt.Errorf(\"invalid config format: %w: %w\", ErrMalformedConfig, err)\n\t}\n\tif len(multi.Apps) == 0 {\n\t\treturn nil, fmt.Errorf(\"invalid config format: no apps: %w\", ErrMalformedConfig)\n\t}\n\treturn &multi, nil\n}\n\n// SaveMultiAppConfig saves config to disk.\nfunc SaveMultiAppConfig(config *MultiAppConfig) error {\n\tdir := GetConfigDir()\n\tif err := vfs.MkdirAll(dir, 0700); err != nil {\n\t\treturn err\n\t}\n\tdata, err := json.MarshalIndent(config, \"\", \"  \")\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn validate.AtomicWrite(GetConfigPath(), append(data, '\\n'), 0600)","sourceCodeStart":213,"sourceCodeEnd":249,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/internal/core/config.go#L213-L249","documentation":"LoadMultiAppConfig reads the multi-app config file and unmarshals it into MultiAppConfig. Malformed JSON fails with this error, typed via ErrMalformedConfig so callers can branch on config corruption rather than string matching.","triggerScenarios":"The config file parsed by auth login/logout/list or profile sync (authLoginRun, authLogoutRun, authListRunWithRecovery, syncLoginUserToProfile) is not valid JSON — e.g. truncated write, manual edit with comments, or a legacy single-app config shape.","commonSituations":"Hand-editing the config and leaving a trailing comma; partial write after crash/disk-full; another tool overwrote the file with YAML/TOML; upgrading from an older CLI whose format differs.","solutions":["Open the config file reported by the CLI (LARKSUITE_CLI_CONFIG_DIR) and fix or remove the JSON syntax error","Back up and delete the corrupted config, then run lark-cli auth init to regenerate it","Check errors.Is(err, errs.ErrMalformedConfig) in code and prompt the user to re-init rather than retrying"],"exampleFix":"// before\n{\n  \"apps\": [{\"name\": \"default\",}\n}\n// after\n{\n  \"apps\": [{\"name\": \"default\"}]\n}","handlingStrategy":"try-catch","validationCode":"data, err := os.ReadFile(configPath)\nif err != nil { return err }\nvar probe map[string]json.RawMessage\nif err := json.Unmarshal(data, &probe); err != nil {\n    return fmt.Errorf(\"config %s is not valid JSON: %w\", configPath, err)\n}","typeGuard":null,"tryCatchPattern":"multi, err := core.LoadMultiAppConfig()\nif err != nil {\n    if errors.Is(err, core.ErrMalformedConfig) {\n        // back up the file and prompt re-init instead of retrying\n        return fmt.Errorf(\"config corrupted; run 'lark-cli auth init': %w\", err)\n    }\n    return err\n}","preventionTips":["Edit the config only with the CLI or a JSON-aware editor","Keep backups before manual edits","Validate JSON after any external tool touches the config file","Watch for partial writes: write to temp then rename atomically"],"tags":["go","config","json","malformed-config"],"backgroundTag":"malformed-config-file","analyzedSha":"7fd6ef3c07182257ce776cdc5a614e122d5bd4b3","analyzedAt":"2026-09-04T21:17:44.649Z","contentChangedAt":"2026-09-04T21:17:44.649Z","schemaVersion":2},"datasetVersion":"2026-09-12T02:17:10.037Z"}