larksuite/cli · error

malformed config

Error message

malformed config

What it means

ErrMalformedConfig marks a config-load failure caused by bad file content — unparseable JSON or a structurally empty apps list — as opposed to a missing or unreadable file. LoadMultiAppConfig wraps JSON unmarshal failures and the zero-apps case with this sentinel so callers classify with errors.Is instead of sniffing message text (see isMalformedConfigError).

Source

Thrown at internal/core/config.go:220

// GetConfigDir returns the config directory path for the current workspace.
// When workspace is local (default), this returns the same path as before
// (LARKSUITE_CLI_CONFIG_DIR or ~/.lark-cli) — fully backward-compatible.
// When workspace is openclaw/hermes, returns base/openclaw or base/hermes.
func GetConfigDir() string {
	return GetRuntimeDir()
}

// GetConfigPath returns the config file path for the current workspace.
func GetConfigPath() string {
	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
}

View on GitHub (pinned to 7fd6ef3c07)

Solutions

  1. Fix the JSON syntax in the config file (validate with a JSON linter)
  2. Re-run `lark-cli config init` to regenerate a valid config with at least one app
  3. Back up and recreate the config if the corruption is unclear

Example fix

// before (config.json)
{ "apps": [ { "appId": "cli_x",
// after
{ "apps": [ { "appId": "cli_x", "appSecret": "..." } ] }
Defensive patterns

Strategy: type-guard

Validate before calling

data, err := os.ReadFile(cfgPath)
var multi core.MultiAppConfig
if err := json.Unmarshal(data, &multi); err != nil || len(multi.Apps) == 0 {
    // config is malformed — run `lark-cli config init`
}

Type guard

func isMalformedConfig(err error) bool { return errors.Is(err, core.ErrMalformedConfig) }

Try / catch

cfg, err := core.LoadMultiAppConfig()
if errors.Is(err, core.ErrMalformedConfig) {
    // distinguish from missing/unreadable file: prompt re-init
}

Prevention

When it happens

Trigger: Calling LoadMultiAppConfig when the config file contains invalid JSON ('invalid config format' wrap) or parses but has len(Apps)==0 ('no apps' wrap).

Common situations: User hand-edited the config file and broke the JSON; an editor or script truncated it; running `config init` output was redirected incorrectly leaving an empty or apps-less file.

Understand the failure class

Related errors


AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04). Data as JSON: /api/errors/5859ef17f0594212. Report an issue: GitHub.