cross-rs/cross · error
no valid choice to pick for image name
Error message
no valid choice to pick for image name
What it means
determine_image_name builds the list of Docker image tags from the current git ref. The match on the ref type (tag, branch, etc.) has no arm covering the encountered ref, so the function bails with this error. It means the CI/git state does not correspond to any tag or recognized branch form the tool knows how to name an image for.
Solutions
- Run the build from a proper git tag or branch checkout so the ref matches a known arm
- Check `git rev-parse --symbolic-full-name HEAD` and confirm it resolves to refs/heads/* or refs/tags/*
- Add a match arm for the new ref type (e.g. default to repository name) in determine_image_name
Example fix
// before
_ => eyre::bail!("no valid choice to pick for image name"),
// after
_ => {
tags.push(target.image_name(repository, "local"));
} Defensive patterns
Strategy: validation
Validate before calling
let r = std::process::Command::new("git").args(["rev-parse","--symbolic-full-name","HEAD"]).output()?;
let name = String::from_utf8_lossy(&r.stdout).trim().to_string();
if !(name.starts_with("refs/heads/") || name.starts_with("refs/tags/")) {
anyhow::bail!("build must run from a branch or tag ref, got: {name}");
} Type guard
fn is_supported_ref(full_name: &str) -> bool {
full_name.starts_with("refs/heads/") || full_name.starts_with("refs/tags/")
} Prevention
- Only run image builds in CI on branch push or tag events
- Fail fast at pipeline start if the git ref is detached or unrecognized
- Keep the ref-type match and CI event types in sync when changing CI providers
When it happens
Trigger: Calling build_docker_image when the current git ref is neither a tag nor a branch pattern matched above (e.g. detached HEAD, an unusual ref like refs/notes/*, or running locally where the ref resolution returns an unmatched variant).
Common situations: Running the xtask docker build outside the expected CI environment (no tag/branch context), or a new CI ref type appearing after a CI system change.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Refusing to push without tag or branch. Specify a…
- unable to find dockerfile for target
- unable to find native dockerfile named
- git tag does not match package version.
- most common base image is
AI-assisted analysis of cross-rs/cross@8c1a8aa4b6 (2026-09-13).
Data as JSON: /api/errors/8619d4ed503b510a.
Report an issue: GitHub.
Appendix: source
Thrown at xtask/src/build_docker_image.rs:434
}
("branch", ref_name) => {
if let Some(gh_queue) = ref_name.strip_prefix("gh-readonly-queue/") {
let (_, source) = gh_queue
.split_once('/')
.ok_or_else(|| eyre::eyre!("invalid gh-readonly-queue branch name"))?;
tags.push(target.image_name(repository, source));
} else {
tags.push(target.image_name(repository, ref_name));
}
if ["staging", "trying"]
.iter()
.any(|branch| branch != &ref_name)
{
tags.push(target.image_name(repository, "edge"));
}
}
_ => eyre::bail!("no valid choice to pick for image name"),
}
Ok(tags)
}
pub fn job_summary(
results: &[Result<ImageTarget, (ImageTarget, eyre::ErrReport)>],
) -> cross::Result<String> {
let mut summary = "# SUMMARY\n\n".to_string();
let success: Vec<_> = results.iter().filter_map(|r| r.as_ref().ok()).collect();
let errors: Vec<_> = results.iter().filter_map(|r| r.as_ref().err()).collect();
if !success.is_empty() {
summary.push_str("## Success\n\n| Target |\n| ------ |\n");
}
for target in success {
writeln!(summary, "| {} |", target.alt())?;
}View on GitHub (pinned to 8c1a8aa4b6)