larksuite/cli · error
appSecret is missing or empty
Error message
appSecret is missing or empty
What it means
ResolveSecretInput is the dispatcher that turns a SecretInput (plain string, "${VAR}" template, or SecretRef object) into a plaintext app secret. This error means the SecretInput is zero: the parsed appSecret field carried neither a Plain string nor a Ref object — i.e. the appSecret key was absent, JSON null, or an empty-string/object combination that left both fields unset.
Source
Thrown at internal/binding/secret_resolve.go:25
"fmt"
"os"
)
// ResolveSecretInput resolves a SecretInput to a plain-text secret string.
// This is the main dispatcher that handles all SecretInput forms:
// - Plain string passthrough
// - "${VAR_NAME}" env template expansion
// - SecretRef object routing to env/file/exec sub-resolvers
//
// The getenv parameter allows injection for testing (typically os.Getenv).
// This function is only called during config bind (cold path).
func ResolveSecretInput(input SecretInput, cfg *SecretsConfig, getenv func(string) string) (string, error) {
if getenv == nil {
getenv = os.Getenv
}
if input.IsZero() {
return "", fmt.Errorf("appSecret is missing or empty")
}
// Plain string form (includes env templates)
if input.IsPlain() {
return resolvePlainOrTemplate(input.Plain, getenv)
}
// SecretRef object form
return resolveSecretRef(input.Ref, cfg, getenv)
}
// resolvePlainOrTemplate handles plain strings and "${VAR}" templates.
func resolvePlainOrTemplate(value string, getenv func(string) string) (string, error) {
if value == "" {
return "", fmt.Errorf("appSecret is empty string")
}
// Check for env template pattern: "${VAR_NAME}"View on GitHub (pinned to 7fd6ef3c07)
Solutions
- Add a non-empty appSecret to the channel in openclaw.json: a literal string, an env template "${FEISHU_APP_SECRET}", or a {"source":"env","id":"..."} SecretRef.
- If the secret must stay out of the file, set appSecret to "${FEISHU_APP_SECRET}" and export that variable before binding.
- In code, guard before calling: if input.IsZero() { return error / skip channel }.
- If appSecret: null was intentional to disable the channel, set "enabled": false instead.
Example fix
// before
{ "channels": { "feishu": { "appId": "cli_a1b2" } } }
// after
{ "channels": { "feishu": { "appId": "cli_a1b2", "appSecret": "${FEISHU_APP_SECRET}" } } } Defensive patterns
Strategy: validation
Validate before calling
if input.IsZero() {
return fmt.Errorf("openclaw config: channels.feishu.appSecret is required before binding")
} Type guard
func hasAppSecret(in binding.SecretInput) bool {
return !in.IsZero()
} Try / catch
secret, err := binding.ResolveSecretInput(input, cfg, os.Getenv)
if err != nil {
if strings.Contains(err.Error(), "appSecret is missing or empty") {
return fmt.Errorf("add appSecret to channels.feishu in openclaw.json: %w", err)
}
return err
} Prevention
- Use a provisioning template for openclaw.json that fails loudly when appSecret is missing.
- Prefer env templates ("${FEISHU_APP_SECRET}") so the key is always present even though the value is external.
- Use "enabled": false, not null/absent appSecret, to disable a channel.
- Lint the config before bind: reject accounts entries lacking appSecret.
When it happens
Trigger: Calling ResolveSecretInput with a SecretInput where IsZero() is true: appSecret omitted from channels.feishu (or an accounts.* entry) in openclaw.json, or explicitly set to null, so UnmarshalJSON never populated Plain or Ref.
Common situations: A fresh openclaw.json template has channels.feishu.appId filled but appSecret still missing; a JSON merge or sed script dropped the appSecret key; a user set appSecret: null expecting it to disable the channel.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- appSecret is empty string
- env variable %q referenced in openclaw.json is not set or em
- unsupported secret source %q
- file provider path is empty
- singleValue file provider expects ref id %q, got %q
AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04).
Data as JSON: /api/errors/3c47bd6f94a92ec0.
Report an issue: GitHub.