Hmbown/CodeWhale · error · anyhow::Error

DeepSeek Harness credentials declare `{key}` more than once

Error message

DeepSeek Harness credentials declare `{key}` more than once

What it means

Thrown by parse_dsh_deepseek_api_key when the same key appears on two different lines: the seen BTreeSet rejects the second occurrence. Duplicate mapping keys are ambiguous in YAML too, so the parser fails closed instead of picking a winner.

Source

Thrown at crates/tui/src/dsh_credentials.rs:54

        let line = raw.trim();
        if line.is_empty() || line.starts_with('#') {
            continue;
        }
        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)

View on GitHub (pinned to 0c42157ee5)

Solutions

  1. Delete the duplicate line so each key appears exactly once
  2. If two values differ, decide which is current and keep only that one
  3. Sort or dedupe the file before importing to catch repeats

Example fix

# before
DEEPSEEK_API_KEY: sk-old
OTHER_KEY: v
DEEPSEEK_API_KEY: sk-new

# after
DEEPSEEK_API_KEY: sk-new
OTHER_KEY: v
Defensive patterns

Strategy: validation

Validate before calling

fn has_duplicate_keys(text: &str) -> Result<()> {
    let mut seen = std::collections::BTreeSet::new();
    for (index, raw) in text.lines().enumerate() {
        let line = raw.trim();
        if line.is_empty() || line.starts_with('#') { continue; }
        let key = line.split_once(':').context("missing colon")?.0.trim().to_string();
        if !seen.insert(key.clone()) {
            return Err(anyhow::anyhow!("line {}: duplicate key {key}", index + 1));
        }
    }
    Ok(())
}

Prevention

When it happens

Trigger: A file containing DEEPSEEK_API_KEY twice — e.g. once commented-out history re-enabled, once appended at the bottom — or a copy-paste that duplicated a block.

Common situations: Appending a new key without noticing one already exists; merging two credential files by concatenation; editors duplicating lines.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@0c42157ee5 (2026-08-20). Data as JSON: /api/errors/db05df3a97dbe824. Report an issue: GitHub.