larksuite/cli · error
unsupported secret source %q
Error message
unsupported secret source %q
What it means
When a SecretInput is the object form, resolveSecretRef dispatches on SecretRef.Source to env/file/exec sub-resolvers. This error means Source held a value outside that set, so no sub-resolver applies. It is normally unreachable for JSON-parsed input because SecretInput.UnmarshalJSON validates source upfront; it fires for programmatically constructed SecretRef values (tests, plugin code) that bypass JSON decoding, or if ref.Source is mutated after unmarshal.
Source
Thrown at internal/binding/secret_resolve.go:79
providerConfig, err := LookupProvider(ref, cfg)
if err != nil {
return "", err
}
// Resolve the effective provider name once so downstream resolvers
// (notably the exec JSON payload) see the config-defaulted value instead
// of the unset literal on ref.Provider.
providerName := ResolveDefaultProvider(ref, cfg)
switch ref.Source {
case "env":
return resolveEnvRef(ref, providerConfig, getenv)
case "file":
return resolveFileRef(ref, providerConfig)
case "exec":
return resolveExecRef(ref, providerName, providerConfig, getenv)
default:
return "", fmt.Errorf("unsupported secret source %q", ref.Source)
}
}
// resolveEnvRef handles {source:"env"} SecretRef.
func resolveEnvRef(ref *SecretRef, pc *ProviderConfig, getenv func(string) string) (string, error) {
// Check allowlist if configured
if len(pc.Allowlist) > 0 {
allowed := false
for _, name := range pc.Allowlist {
if name == ref.ID {
allowed = true
break
}
}
if !allowed {
return "", fmt.Errorf("environment variable %q is not allowlisted in provider", ref.ID)
}
}View on GitHub (pinned to 7fd6ef3c07)
Solutions
- Use one of the supported sources exactly: "env", "file", or "exec" in the SecretRef.
- For a real secret manager, use source:"exec" with a command that fetches the secret from vault/kms and prints the value.
- In code, validate before calling: if !validSources[ref.Source] (or a local switch on the same set) reject early.
- If going through JSON, rely on UnmarshalJSON which rejects bad sources earlier with its own clearer message.
Example fix
// before
ref := &binding.SecretRef{Source: "vault", ID: "feishu/secret"}
// after
ref := &binding.SecretRef{Source: "exec", ID: "feishu/secret"} // exec command fetches from vault Defensive patterns
Strategy: type-guard
Validate before calling
func validateSecretRef(ref *binding.SecretRef) error {
switch ref.Source {
case "env", "file", "exec":
return nil
default:
return fmt.Errorf("source must be env|file|exec, got %q", ref.Source)
}
} Type guard
func isSupportedSource(src string) bool {
return src == "env" || src == "file" || src == "exec"
} Try / catch
secret, err := binding.ResolveSecretInput(binding.SecretInput{Ref: ref}, cfg, os.Getenv)
if err != nil {
if strings.HasPrefix(err.Error(), "unsupported secret source") {
return fmt.Errorf("use source env|file|exec (for vault/kms use exec): %w", err)
}
return err
} Prevention
- Only build SecretRef values through JSON decoding, where UnmarshalJSON validates source upfront.
- Treat exec as the escape hatch for unsupported backends (vault, kms) instead of inventing a new source.
- Match source strings exactly: lowercase, no whitespace, no URL schemes like "file://".
- Centralize SecretRef construction in one helper that validates against the env|file|exec set.
When it happens
Trigger: Constructing SecretRef{Source: "kms" | "vault" | "" | "env " (with space)} in Go and calling ResolveSecretInput directly, or any code path that builds the union without going through UnmarshalJSON's validSources check. Note provider *names* are resolved via config; only Source is switch-matched here.
Common situations: A developer extends the ref with a new backend (e.g. source:"vault") expecting library support that does not exist yet; a typo like "Environment" or "file://" in a programmatically built ref; test fixtures with placeholder sources.
Related errors
- appSecret is missing or empty
- appSecret is empty string
- env variable %q referenced in openclaw.json is not set or em
- 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/2edb637a8e14de11.
Report an issue: GitHub.