larksuite/cli · error

exec provider command is empty

Error message

exec provider command is empty

What it means

prepareExecRun validates the exec provider configuration before spawning any child process. It throws this error when the provider config's Command field is an empty string, meaning there is no executable to invoke for resolving the secret. This is a pure-data validation step that happens before path auditing, so no process is ever spawned.

Source

Thrown at internal/binding/secret_resolve_exec.go:69

// resolved effective alias (honours secrets.defaults.exec from openclaw.json).
func resolveExecRef(ref *SecretRef, providerName string, pc *ProviderConfig, getenv func(string) string) (string, error) {
	prep, err := prepareExecRun(ref, providerName, pc, getenv)
	if err != nil {
		return "", err
	}
	stdout, err := runExecCommand(prep)
	if err != nil {
		return "", err
	}
	return extractExecSecret(stdout, ref.ID, effectiveJSONOnly(pc))
}

// prepareExecRun audits the command path, marshals the JSON request,
// assembles the minimal child env, and resolves timeout / output limits.
// Never spawns a process — the returned execRun is pure data.
func prepareExecRun(ref *SecretRef, providerName string, pc *ProviderConfig, getenv func(string) string) (*execRun, error) {
	if pc.Command == "" {
		return nil, fmt.Errorf("exec provider command is empty")
	}

	securePath, err := AssertSecurePath(AuditParams{
		TargetPath:            pc.Command,
		Label:                 "exec provider command",
		TrustedDirs:           pc.TrustedDirs,
		AllowInsecurePath:     pc.AllowInsecurePath,
		AllowReadableByOthers: true, // exec commands are typically 755
		AllowSymlinkPath:      pc.AllowSymlinkCommand,
	})
	if err != nil {
		return nil, fmt.Errorf("exec provider security audit failed: %w", err)
	}

	reqJSON, err := marshalExecRequest(ref, providerName)
	if err != nil {
		return nil, err
	}

View on GitHub (pinned to 7fd6ef3c07)

Solutions

  1. Set the command field in the exec provider config to the absolute path of the resolver executable
  2. Verify the config section you edited belongs to the provider actually being used (check provider name nesting/indentation)
  3. Remove the exec provider entirely if it is unused instead of leaving an empty stub

Example fix

# before
providers:
  vault-cli:
    type: exec

# after
providers:
  vault-cli:
    type: exec
    command: /usr/local/bin/vault-resolver
Defensive patterns

Strategy: validation

Validate before calling

// validate provider config before resolution
if p.Type == "exec" && strings.TrimSpace(p.Command) == "" {
    return fmt.Errorf("exec provider %q: command must be set to the resolver executable path", p.Name)
}

Try / catch

secret, err := resolveSecretRef(ctx, ref)
if err != nil {
    if strings.Contains(err.Error(), "exec provider command is empty") {
        return fmt.Errorf("provider %s has no command configured; fix the provider config", ref.Provider)
    }
    return err
}

Prevention

When it happens

Trigger: A provider of type exec is declared in the secret-provider config but its command field is omitted or set to ""; resolveExecRef -> prepareExecRun hits `if pc.Command == ""`.

Common situations: Copy-pasting a provider config template and leaving the command placeholder empty; a config merge/override zeroing out the command field; hand-writing YAML/TOML where the command key was deleted or indented under the wrong provider.

Related errors


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