alibaba/open-code-review · error
%s produced a control byte 0x%02X at offset %d; a credential
Error message
%s produced a control byte 0x%02X at offset %d; a credential must not contain control characters
What it means
After the line-break check, every byte of the command output is scanned for control characters (bytes < 0x20 except TAB, and DEL 0x7f). A credential containing such a byte would later be rejected by net/http with an opaque header error, so the loader fails early and names the byte and its offset — offsets are into the pre-TrimSpace output, exactly what the command produced.
Source
Thrown at internal/llm/keycmd.go:124
// 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 can
// plausibly append by accident. Offsets are therefore into the pre-TrimSpace
// string, which is what the command actually produced.
for i := 0; i < len(trimmed); i++ {
if b := trimmed[i]; (b < 0x20 && b != '\t') || b == 0x7f {
return "", fmt.Errorf("%s produced a control byte 0x%02X at offset %d; a credential must not contain control characters", label, b, i)
}
}
key := strings.TrimSpace(trimmed)
if key == "" {
return "", fmt.Errorf("%s produced empty output", label)
}
return key, nil
}
View on GitHub (pinned to 5cf97d0d15)
Solutions
- Check the reported offset and hex byte against the raw output (<your-cmd> | xxd | head) to find the corruption source
- Remove ANSI coloring from the helper command (NO_COLOR=1 or a --no-color flag)
- Fix the decryption/decoding step so the command emits plain ASCII text
- Re-create/re-rotate the credential if the stored value itself is corrupted
Example fix
// before keyCmd: "credential-decrypt blob.enc" // emits binary // after keyCmd: "NO_COLOR=1 credential-decrypt --text blob.enc"
Defensive patterns
Strategy: validation
Validate before calling
out, _ := exec.Command("sh", "-c", "<your-key-cmd>").Output()
for i, b := range out {
if (b < 0x20 && b != '\t') || b == 0x7f { /* control byte at offset i; fix source */ }
} Prevention
- Disable ANSI color in helper commands (NO_COLOR=1)
- Ensure decryption steps emit plaintext, not binary
- Validate the stored secret is plain ASCII after rotation
When it happens
Trigger: The credential command emits binary or corrupted data — printf with an escaped NUL, a decrypted blob instead of a token, a truncated binary secret, or ANSI escape sequences (ESC 0x1b) from colored output.
Common situations: Base64-decode mistakes leaving binary bytes; colored CLI output with ANSI codes; a mis-decrypted age/gpg payload; corrupted stored secrets.
Related errors
- %s timed out after %s: %w
- %s produced more than 64KiB of output
- %s failed: %w
- %s produced multi-line output; expected a single credential
- %s produced empty output
AI-assisted analysis of alibaba/open-code-review@5cf97d0d15 (2026-09-02).
Data as JSON: /api/errors/ffb1083d8adde355.
Report an issue: GitHub.