larksuite/cli · critical
ErrMalformedConfig
ErrMalformedConfig
Error message
invalid config format: %w: %w
What it means
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.
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
Example fix
// before
{
"apps": [{"name": "default",}
}
// after
{
"apps": [{"name": "default"}]
} Defensive patterns
Strategy: try-catch
Validate before calling
data, err := os.ReadFile(configPath)
if err != nil { return err }
var probe map[string]json.RawMessage
if err := json.Unmarshal(data, &probe); err != nil {
return fmt.Errorf("config %s is not valid JSON: %w", configPath, err)
} Try / catch
multi, err := core.LoadMultiAppConfig()
if err != nil {
if errors.Is(err, core.ErrMalformedConfig) {
// back up the file and prompt re-init instead of retrying
return fmt.Errorf("config corrupted; run 'lark-cli auth init': %w", err)
}
return err
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- anchor outside sheet
- appSecret must be a string or
- appSecret must be a string or
- array default for requires exactly items, got
- fetch bot info: unmarshal
AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04).
Data as JSON: /api/errors/00460b88f8bd9e90.
Report an issue: GitHub.
Appendix: source
Thrown at internal/core/config.go:231
return filepath.Join(GetConfigDir(), "config.json")
}
// ErrMalformedConfig marks a config-load failure caused by malformed file
// content (unparseable JSON, structurally empty) rather than a missing or
// unreadable file. Callers classify with errors.Is rather than sniffing the
// message text.
var ErrMalformedConfig = errors.New("malformed config")
// LoadMultiAppConfig loads multi-app config from disk.
func LoadMultiAppConfig() (*MultiAppConfig, error) {
data, err := vfs.ReadFile(GetConfigPath())
if err != nil {
return nil, err
}
var multi MultiAppConfig
if err := json.Unmarshal(data, &multi); err != nil {
return nil, fmt.Errorf("invalid config format: %w: %w", ErrMalformedConfig, err)
}
if len(multi.Apps) == 0 {
return nil, fmt.Errorf("invalid config format: no apps: %w", ErrMalformedConfig)
}
return &multi, nil
}
// SaveMultiAppConfig saves config to disk.
func SaveMultiAppConfig(config *MultiAppConfig) error {
dir := GetConfigDir()
if err := vfs.MkdirAll(dir, 0700); err != nil {
return err
}
data, err := json.MarshalIndent(config, "", " ")
if err != nil {
return err
}
return validate.AtomicWrite(GetConfigPath(), append(data, '\n'), 0600)View on GitHub (pinned to 7fd6ef3c07)