Hmbown/CodeWhale · error
DeepSeek Harness credentials line {} is invalid: {reason}
Error message
DeepSeek Harness credentials line {} is invalid: {reason} What it means
While parsing DeepSeek Harness credentials `KEY: value` lines, the value is passed through `unquote_yaml_string`; any parse failure is reported with the 1-based line number and the underlying reason (dsh_credentials.rs:57). Key identifier syntax and duplicate keys were already validated, so this failure is specifically about the value's quoting.
Source
Thrown at crates/tui/src/dsh_credentials.rs:57
}
let Some((key, value)) = line.split_once(':') else {
bail!(
"DeepSeek Harness credentials line {} is not `KEY: value`",
index + 1
);
};
let key = key.trim();
if !is_posix_identifier(key) {
bail!(
"DeepSeek Harness credentials line {} has a non-identifier key",
index + 1
);
}
if !seen.insert(key.to_string()) {
bail!("DeepSeek Harness credentials declare `{key}` more than once");
}
let value = unquote_yaml_string(value.trim()).map_err(|reason| {
anyhow::anyhow!(
"DeepSeek Harness credentials line {} is invalid: {reason}",
index + 1
)
})?;
if value.is_empty() {
bail!(
"DeepSeek Harness credentials line {} has an empty value",
index + 1
);
}
if key == DEEPSEEK_API_KEY_REF {
found = Some(value);
}
}
Ok(found)
}
fn is_posix_identifier(value: &str) -> bool {View on GitHub (pinned to 8880682c63)
Solutions
- Open the credentials file at the reported 1-based line
- Write the value plain (`KEY: value`) when it has no special characters
- Or wrap the value in one balanced pair of double quotes, escaping any inner quotes
Example fix
# before (line 3) DEEPSEEK_API_KEY: "sk-abc # after DEEPSEEK_API_KEY: sk-abc123
Defensive patterns
Strategy: validation
Validate before calling
fn credentials_lint(text: &str) -> Result<()> {
for (i, line) in text.lines().filter(|l| !l.trim().is_empty()).enumerate() {
let quotes = line.matches('"').count();
anyhow::ensure!(quotes % 2 == 0, "line {} has unbalanced quotes", i + 1);
}
Ok(())
} Type guard
fn looks_like_credentials_line(line: &str) -> bool {
let mut parts = line.splitn(2, ':');
matches!(parts.next(), Some(k) if !k.trim().is_empty())
&& matches!(parts.next(), Some(v) if !v.trim().is_empty())
} Try / catch
match load_dsh_credentials(&path) {
Ok(credentials) => credentials,
Err(err) if err.to_string().contains("credentials line") => {
eprintln!("fix the quoting on the reported line: {err}");
anyhow::bail!("credentials file rejected");
}
Err(err) => return Err(err),
} Prevention
- Generate credentials files with tooling instead of hand edits
- Prefer plain unquoted values unless characters require quoting
- Lint for unbalanced quotes before loading
When it happens
Trigger: A value with an unterminated quote (`DEEPSEEK_API_KEY: "sk-abc`), mismatched quote pairs, or escape sequences that `unquote_yaml_string` rejects.
Common situations: Hand-edited credentials file; copy-paste from docs or chat that mangles quotes; secrets containing quote characters pasted without proper quoting.
Related errors
- invalid JSON payload at key {MCP_SERVER_DEFINITIONS_KEY}; co
- external credential consent for {}: {error}
- Kimi CLI credential import is unsupported. Codewhale does no
- unterminated environment placeholder in MCP config value
- parallel(): expected an array of thunks
AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16).
Data as JSON: /api/errors/fe53f80c06c4ec1f.
Report an issue: GitHub.