alibaba/open-code-review · error
failed
Error message
%s failed: %w
What it means
If the key command exits non-zero or cannot be executed, the failure is reported as `<label> failed: %w` wrapping the exec error. This covers non-zero exit codes and command-not-found (the shell exits non-zero and prints its message on the child's stderr). exec.ErrWaitDelay is deliberately excluded, since it only means an orphaned grandchild holds the pipe while the output is already valid.
Solutions
- Run the command manually with the same user/environment and check its exit code and stderr
- Fix the underlying helper failure (credentials, config, permissions)
- Correct the command name/path — ensure the binary is in PATH or use an absolute path
- Inspect the wrapped exec.ExitError for the exit code; check the shell's stderr
Example fix
// before keyCmd: "op read op://vault/item/cred" // op not installed on CI // after keyCmd: "/usr/local/bin/op read op://vault/item/cred" // installed, absolute path
Defensive patterns
Strategy: try-catch
Validate before calling
if _, err := exec.LookPath("<your-key-cmd-binary>"); err != nil { /* not in PATH; install or use an absolute path */ } Try / catch
key, err := resolveKeyCmd(ctx, cfg)
if err != nil {
var exitErr *exec.ExitError
if errors.As(err, &exitErr) {
log.Printf("helper exited %d; check its auth/config", exitErr.ExitCode())
}
return err
} Prevention
- Use absolute paths for credential binaries
- Verify PATH in cron/CI environments matches your shell
- Run the helper manually before wiring it into configuration
When it happens
Trigger: The configured credential command exits non-zero — wrong password, missing binary in PATH, denied permissions, or the command name does not exist.
Common situations: Typo in the command path; helper not installed in the environment the tool runs in (cron/CI PATH differs); secrets CLI failing auth; script erroring on a missing config file.
Related errors
- produced a control byte 0x%02X at offset ; a credential…
- produced empty output
- produced more than 64KiB of output
- produced multi-line output; expected a single credential…
- timed out after
AI-assisted analysis of alibaba/open-code-review@5cf97d0d15 (2026-09-02).
Data as JSON: /api/errors/efdc744900536ee6.
Report an issue: GitHub.
Appendix: source
Thrown at internal/llm/keycmd.go:101
err := c.Run()
// Checked first so a timeout reports as such instead of as the SIGKILL exit
// status it produces. (Run has already joined every stdout copier, so the
// buffer below is safe to read on all paths.)
if ctx.Err() == context.DeadlineExceeded {
// Wrap ctx.Err() so callers can errors.Is(err, context.DeadlineExceeded).
return "", fmt.Errorf("%s timed out after %s: %w", label, keyCmdTimeout, ctx.Err())
}
if out.overflow {
return "", fmt.Errorf("%s produced more than 64KiB of output", label)
}
// ErrWaitDelay only means an orphaned grandchild still holds the pipe; the
// command itself exited fine and its output is already buffered, so use it
// rather than surfacing an exec-internal error.
if err != nil && !errors.Is(err, exec.ErrWaitDelay) {
// Covers non-zero exit and command-not-found (the shell exits non-zero
// and prints its not-found message on the child's stderr). ExitError.Stderr
// stays nil because we assigned c.Stderr, so no output can leak here.
return "", fmt.Errorf("%s failed: %w", label, err)
}
// Trim a trailing line break; multi-line output past that is ambiguous and refused.
// ContainsAny (not Contains "\n") so a lone interior CR is caught too: TrimRight
// leaves it, TrimSpace below only strips the edges, and a CR inside a credential
// makes net/http reject the Authorization header with an opaque error.
trimmed := strings.TrimRight(out.buf.String(), "\r\n")
if strings.ContainsAny(trimmed, "\n\r") {
return "", fmt.Errorf("%s produced multi-line output; expected a single credential (pipe through 'head -n1' if your command prints more)", label)
}
// Same reason as the line-break check, wider net: httpguts.ValidHeaderFieldValue
// (what net/http enforces) rejects every byte below 0x20 except SP and TAB, plus
// DEL. A NUL or VT smuggled in by e.g. `printf 'sk-a\0b'` would otherwise reach
// net/http as the opaque `invalid header field value for "Authorization"`.
//
// Deliberately before the TrimSpace below, so a trailing control byte is an
// error naming its offset rather than silently stripped: only TAB, SP and the
// line breaks already handled above are things a credential command canView on GitHub (pinned to 5cf97d0d15)