{"record":{"id":"4d0ece3aeb3f3e1e","repo":"larksuite/cli","slug":"exec-provider-command-is-empty","errorCode":null,"errorMessage":"exec provider command is empty","messagePattern":"exec provider command is empty","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/binding/secret_resolve_exec.go","lineNumber":69,"sourceCode":"// resolved effective alias (honours secrets.defaults.exec from openclaw.json).\nfunc resolveExecRef(ref *SecretRef, providerName string, pc *ProviderConfig, getenv func(string) string) (string, error) {\n\tprep, err := prepareExecRun(ref, providerName, pc, getenv)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tstdout, err := runExecCommand(prep)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\treturn extractExecSecret(stdout, ref.ID, effectiveJSONOnly(pc))\n}\n\n// prepareExecRun audits the command path, marshals the JSON request,\n// assembles the minimal child env, and resolves timeout / output limits.\n// Never spawns a process — the returned execRun is pure data.\nfunc prepareExecRun(ref *SecretRef, providerName string, pc *ProviderConfig, getenv func(string) string) (*execRun, error) {\n\tif pc.Command == \"\" {\n\t\treturn nil, fmt.Errorf(\"exec provider command is empty\")\n\t}\n\n\tsecurePath, err := AssertSecurePath(AuditParams{\n\t\tTargetPath:            pc.Command,\n\t\tLabel:                 \"exec provider command\",\n\t\tTrustedDirs:           pc.TrustedDirs,\n\t\tAllowInsecurePath:     pc.AllowInsecurePath,\n\t\tAllowReadableByOthers: true, // exec commands are typically 755\n\t\tAllowSymlinkPath:      pc.AllowSymlinkCommand,\n\t})\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"exec provider security audit failed: %w\", err)\n\t}\n\n\treqJSON, err := marshalExecRequest(ref, providerName)\n\tif err != nil {\n\t\treturn nil, err\n\t}","sourceCodeStart":51,"sourceCodeEnd":87,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/internal/binding/secret_resolve_exec.go#L51-L87","documentation":"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.","triggerScenarios":"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 == \"\"`.","commonSituations":"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.","solutions":["Set the command field in the exec provider config to the absolute path of the resolver executable","Verify the config section you edited belongs to the provider actually being used (check provider name nesting/indentation)","Remove the exec provider entirely if it is unused instead of leaving an empty stub"],"exampleFix":"# before\nproviders:\n  vault-cli:\n    type: exec\n\n# after\nproviders:\n  vault-cli:\n    type: exec\n    command: /usr/local/bin/vault-resolver","handlingStrategy":"validation","validationCode":"// validate provider config before resolution\nif p.Type == \"exec\" && strings.TrimSpace(p.Command) == \"\" {\n    return fmt.Errorf(\"exec provider %q: command must be set to the resolver executable path\", p.Name)\n}","typeGuard":null,"tryCatchPattern":"secret, err := resolveSecretRef(ctx, ref)\nif err != nil {\n    if strings.Contains(err.Error(), \"exec provider command is empty\") {\n        return fmt.Errorf(\"provider %s has no command configured; fix the provider config\", ref.Provider)\n    }\n    return err\n}","preventionTips":["Always set an absolute command path when defining an exec provider","Validate provider configs at load time (fail fast before any secret resolution)","Don't leave stub/placeholder provider entries in config files"],"tags":["secrets","configuration","exec"],"backgroundTag":"missing-exec-command","analyzedSha":"7fd6ef3c07182257ce776cdc5a614e122d5bd4b3","analyzedAt":"2026-09-04T21:17:44.649Z","contentChangedAt":"2026-09-04T21:17:44.649Z","schemaVersion":2},"datasetVersion":"2026-09-12T02:17:10.037Z"}