Hmbown/CodeWhale · error

DeepSeek Harness credentials line

Error message

DeepSeek Harness credentials line {} has an empty value

What it means

parse_dsh_deepseek_api_key parses the dsh CLI's `.credentials.yaml` as a strict mapping of POSIX identifiers to non-empty quoted/plain strings. Any line of the form `KEY:` (or `KEY: ""`) with an empty value fails closed, because the parser refuses to treat an empty string as a credential. This guards against silently importing a blank DeepSeek API key.

Solutions

  1. Run `dsh` login/auth to populate DEEPSEEK_API_KEY with a real key, then retry the Codewhale import.
  2. Open the credentials file reported in the error and fill in the empty value on the indicated line number (1-indexed).
  3. If you do not want dsh import, set DEEPSEEK_API_KEY directly via Codewhale's own config/auth path instead of the external-consent grant.
  4. Remove the malformed line entirely if the key is not needed — blank lines and `#` comments are skipped.

Example fix

// before: $DSH_HOME/.credentials.yaml
DEEPSEEK_API_KEY:
// after
DEEPSEEK_API_KEY: "sk-...actual-key..."
Defensive patterns

Strategy: validation

Validate before calling

// Pre-check the dsh credentials text before import
fn has_empty_credential_value(text: &str) -> Option<usize> {
    text.lines().enumerate().find_map(|(i, raw)| {
        let line = raw.trim();
        if line.is_empty() || line.starts_with('#') { return None; }
        let value = line.split_once(':')?.1.trim();
        (value.is_empty() || value == "\"\"").then(|| i + 1)
    })
}

Try / catch

match deepseek_api_key_from_grant(&grant) {
    Ok(Some(key)) if !key.is_empty() => use(key),
    Ok(_) => println!("no DEEPSEEK_API_KEY in dsh credentials"),
    Err(e) if e.to_string().contains("empty value") => eprintln!("run `dsh auth` to set the key: {e}"),
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling `deepseek_api_key_from_grant` on a granted `$DSH_HOME/.credentials.yaml` that contains a non-comment, non-blank line whose value after the colon is empty (e.g. `DEEPSEEK_API_KEY:` or `DEEPSEEK_API_KEY: ""`).

Common situations: The dsh CLI was run but authentication never completed, so it wrote the key with an empty placeholder value; the user manually edited the credentials file and cleared the value; a provisioning script wrote an env-style file with the value to be filled in later.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/b19486848ef7200c. Report an issue: GitHub.

Appendix: source

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

        };
        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 {
    let mut chars = value.chars();
    matches!(chars.next(), Some('A'..='Z' | 'a'..='z' | '_'))
        && chars.all(|ch| matches!(ch, 'A'..='Z' | 'a'..='z' | '0'..='9' | '_'))
}

fn unquote_yaml_string(value: &str) -> Result<String, &'static str> {

View on GitHub (pinned to 73e0f67d83)