Hmbown/CodeWhale · error

This command authenticates with a Codewhale account API…

Error message

This command authenticates with a Codewhale account API key. Set {MACHINE_KEY_ENV}, or create one with `codewhale account api-keys create` after `codewhale login`.

What it means

`MachineKeyStore::require` validates and returns the configured Codewhale machine API key; if none is set (the resolved secret is empty/unset), it throws this message telling the user how to supply one via the environment variable or by creating it with the CLI.

Solutions

  1. Export the key: set MACHINE_KEY_ENV to a valid Codewhale API key.
  2. Create one if needed: `codewhale login` then `codewhale account api-keys create`.
  3. If a secret-store slot exists but is empty, re-set it (`codewhale account keys set`) or bypass with the env var.

Example fix

// before (CI)
codewhale account providers list
// after
export MACHINE_KEY_ENV="cw_..."  # actual var name per docs
codewhale account providers list
Defensive patterns

Strategy: validation

Validate before calling

let key = std::env::var("MACHINE_KEY_ENV").unwrap_or_default();
if key.trim().is_empty() {
    eprintln!("set MACHINE_KEY_ENV or run: codewhale account api-keys create");
    std::process::exit(2);
}

Prevention

When it happens

Trigger: Running a cloud-account command that calls `require()` while MACHINE_KEY_ENV is unset, empty, or reads as empty from the secret store.

Common situations: Fresh machine/CI environment without the key exported; key exported under the wrong variable name; a secret-store slot that exists but holds an empty string.

Understand the failure class

Background: "API key is required" / "API key not found" / "No API key was set": the missing-api-key error family across 16 libraries — this error's family across 16 libraries.

Related errors


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

Appendix: source

Thrown at crates/cli/src/cloud/machine.rs:204

                .filter(|value| !value.trim().is_empty()),
        }
    }

    /// Whether a machine credential is present at all, valid or not.
    #[must_use]
    pub(crate) fn is_present(&self) -> bool {
        self.raw.is_some()
    }

    /// Validate the key if one is set.
    pub(crate) fn resolve(&self) -> Result<Option<MachineKey>> {
        self.raw.as_deref().map(MachineKey::parse).transpose()
    }

    /// Validate the key, requiring one to be set.
    pub(crate) fn require(&self) -> Result<MachineKey> {
        self.resolve()?.ok_or_else(|| {
            anyhow!(
                "This command authenticates with a Codewhale account API key. \
Set {MACHINE_KEY_ENV}, or create one with `codewhale account api-keys create` after \
`codewhale login`."
            )
        })
    }
}

// ---------------------------------------------------------------------------
// Base URL
// ---------------------------------------------------------------------------

/// Resolve the account API origin.
///
/// Order: explicit `--api-base`, then `CODEWHALE_API_BASE`, then whatever the
/// device flow already uses, then the production default. The flag outranks
/// the variable for the same reason `--api-key` would outrank the environment:
/// the nearer, more deliberate signal wins.

View on GitHub (pinned to 73e0f67d83)