lima-vm/lima · error

redirect %#q must not include a branch/tag/sha (from %#q)

Error message

redirect %#q must not include a branch/tag/sha (from %#q)

What it means

validateGitHubRedirect rejects redirect values containing '@', because the branch/tag is appended programmatically (from the original request or the default branch). A pinned redirect like github:ORG/REPO@v1.0 would be ambiguous or could bypass the intended branch propagation, so it fails with "redirect <value> must not include a branch/tag/sha (from <url>)".

Source

Thrown at pkg/limatmpl/github.go:238

	if resp.StatusCode != http.StatusOK {
		return "", fmt.Errorf("file %#q not found or inaccessible: status %d", resp.Request.URL, resp.StatusCode)
	}
	body, err := io.ReadAll(resp.Body)
	if err != nil {
		return "", fmt.Errorf("failed to read %#q content: %w", resp.Request.URL, err)
	}
	return validateGitHubRedirect(string(body), org, origBranch, resp.Request.URL.String())
}

func validateGitHubRedirect(body, org, origBranch, url string) (string, error) {
	redirect, _, _ := strings.Cut(body, "\n")
	redirect = strings.TrimSpace(redirect)

	if !strings.HasPrefix(redirect, "github:"+org+"/") {
		return "", fmt.Errorf("redirect %#q is not a `github:%s` URL (from %#q)", redirect, org, url)
	}
	if strings.ContainsRune(redirect, '@') {
		return "", fmt.Errorf("redirect %#q must not include a branch/tag/sha (from %#q)", redirect, url)
	}
	// If the origBranch is empty, then we need to look up the default branch in the redirect
	if origBranch != "" {
		redirect += "@" + origBranch
	}
	return redirect, nil
}

View on GitHub (pinned to dd909d0973)

Solutions

  1. Remove the @branch/@tag/@sha portion from the redirect file's first line, leaving github:ORG/REPO/PATH
  2. If you need a pinned version, reference that pinned URL directly in your limactl command instead of via the redirect
  3. Update the upstream redirect file and retry

Example fix

// redirect file first line, before
github:lima-vm/alpine-lim@v1.0
// after
github:lima-vm/alpine-lim
Defensive patterns

Strategy: validation

Validate before calling

func redirectHasNoRef(body string) bool {
    line, _, _ := strings.Cut(body, "\n")
    return !strings.Contains(line, "@")
}
if !redirectHasNoRef(redirectFile) {
    return errors.New("redirect must not pin a branch/tag/sha")
}

Type guard

func isUnpinnedRedirect(content string) bool {
    line, _, _ := strings.Cut(content, "\n")
    return !strings.ContainsRune(strings.TrimSpace(line), '@')
}

Try / catch

url, err := transformGitHubURL(ctx, ref)
if err != nil && strings.Contains(err.Error(), "must not include a branch/tag/sha") {
    return fmt.Errorf("%w (hint: strip @branch/@tag/@sha from the redirect file's first line)", err)
}

Prevention

When it happens

Trigger: resolveGitHubSymlink or resolveGitHubRedirect passes redirect content to validateGitHubRedirect and the first line contains '@' anywhere, e.g. github:ORG/REPO@main/path.yaml or a sha-pinned redirect.

Common situations: Template authors pinning redirects to a tag or commit SHA for stability; copy-pasting a full github: URL including its @branch into a redirect file; examples written before the no-@ rule was enforced.

Related errors


AI-assisted analysis of lima-vm/lima@dd909d0973 (2026-09-01). Data as JSON: /api/errors/7eacf7f47f07fdf3. Report an issue: GitHub.