Hmbown/CodeWhale · error · anyhow::Error

a CNB access token is not configured in the Codewhale…

Error message

a CNB access token is not configured in the Codewhale service slot; the branch was pushed but no pull request was opened

What it means

open_pr_cnb in dispatch_runner.rs pushes a branch then opens a pull request on cnb.cool. Before making the HTTP call it reads the CNB access token from the Codewhale service slot via read_service_token; when the slot is empty it fails with this error. The message deliberately notes the branch was already pushed so the user knows remote state exists and only the PR step failed.

Solutions

  1. Provision the CNB access token into the Codewhale service slot (the `cnb` slot read by read_service_token), then re-run the open command.
  2. Verify the token store location/permissions so the service slot is readable by the TUI process.
  3. The branch is already pushed; after configuring the token, open the PR manually on cnb.cool or re-run only the PR step.

Example fix

// before: CNB token missing
$ codewhale open --job <id>
// after: provision the token, then retry
$ codewhale service set cnb --token <CNB_ACCESS_TOKEN>
$ codewhale open --job <id>
Defensive patterns

Strategy: validation

Validate before calling

if read_service_token("cnb").is_none() {
    eprintln!("CNB token missing; configure the service slot before opening a PR");
    return;
}

Prevention

When it happens

Trigger: Calling `open` on a cloud job with a CNB patch receipt when no `cnb` service token has been stored (read_service_token("cnb") returns None).

Common situations: Fresh install where the CNB token was never provisioned into the service slot; token store reset or rotated away; running on a machine/container without the credentials mounted; typo in the slot name during setup.

Related errors


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

Appendix: source

Thrown at crates/tui/src/dispatch_runner.rs:669

        serde_json::from_str(&text).context("Gitee returned invalid JSON")?;
    parsed
        .get("html_url")
        .and_then(serde_json::Value::as_str)
        .map(str::trim)
        .filter(|url| url.starts_with("https://"))
        .map(|url| url.to_string())
        .ok_or_else(|| anyhow!("Gitee did not report a pull request URL; refusing to invent one."))
}

fn open_pr_cnb(
    slug: &str,
    job: &CloudJob,
    patch: &PatchReceipt,
    title: &str,
    body: &str,
) -> Result<String> {
    let token = read_service_token("cnb").ok_or_else(|| {
        anyhow!("a CNB access token is not configured in the Codewhale service slot; the branch was pushed but no pull request was opened")
    })?;
    let url = validate_outbound_origin(&cnb_pr_url(slug))?;
    let response = crate::tls::reqwest_blocking_client_builder()
        .connect_timeout(std::time::Duration::from_secs(8))
        .timeout(std::time::Duration::from_secs(30))
        .redirect(reqwest::redirect::Policy::none())
        .build()
        .context("could not initialize the CNB client")?
        .post(url)
        .bearer_auth(&token)
        .json(&serde_json::json!({
            "title": title,
            "head": job.branch,
            "base": patch.base_branch,
            "body": body,
        }))
        .send()
        .context("could not reach CNB")?;

View on GitHub (pinned to 73e0f67d83)