gastownhall/beads · error
failed to canonicalize URL: %w
Error message
failed to canonicalize URL: %w
What it means
After obtaining the repository's remote URL from git, ComputeRepoIDForPathWithSource canonicalizes it (normalizing scheme, host, port, .git suffix etc.) before hashing. If canonicalizeGitURL fails, the remote URL cannot be parsed into a usable form and this wrapped error is returned, aborting remote-based fingerprinting.
Source
Thrown at internal/beads/fingerprint.go:70
output, err := runGitInRepo(repoPath, "config", "--get", "remote.origin.url")
if err != nil {
// No remote configured — fall back to path-based fingerprint.
// Use --git-common-dir to derive the main repo root so that
// worktrees produce the same fingerprint as the main checkout.
repoRoot, rootErr := mainRepoRootForPath(repoPath)
if rootErr != nil {
return "", "", fmt.Errorf("not a git repository")
}
normalized := normalizedRepoPath(repoRoot)
hash := sha256.Sum256([]byte(normalized))
return hex.EncodeToString(hash[:16]), RepoIDSourcePath, nil
}
repoURL := strings.TrimSpace(string(output))
canonical, err := canonicalizeGitURL(repoURL)
if err != nil {
return "", "", fmt.Errorf("failed to canonicalize URL: %w", err)
}
hash := sha256.Sum256([]byte(canonical))
return hex.EncodeToString(hash[:16]), RepoIDSourceRemote, nil
}
func canonicalizeGitURL(rawURL string) (string, error) {
rawURL = strings.TrimSpace(rawURL)
if strings.Contains(rawURL, "://") {
u, err := url.Parse(rawURL)
if err != nil {
return "", fmt.Errorf("invalid URL: %w", err)
}
host := strings.ToLower(u.Hostname())
if port := u.Port(); port != "" && port != "22" && port != "80" && port != "443" {
host = host + ":" + portView on GitHub (pinned to 71377f2769)
Solutions
- Inspect the remote URL (`git remote -v`) and fix malformed entries in .git/config
- Re-set the remote: `git remote set-url origin <correct-url>`
- If the URL is valid but unsupported, normalize it to a standard https:// or git@host:path form
- As a workaround, ensure a clean remote is configured so path-based fallback is not needed
Example fix
// before (.git/config) [remote "origin"] url = https:/github.com/acme/repo // after git remote set-url origin https://github.com/acme/repo.git
Defensive patterns
Strategy: validation
Validate before calling
out, _ := exec.Command("git", "remote", "get-url", "origin").Output()
u := strings.TrimSpace(string(out))
if u != "" && !strings.Contains(u, "://") && !strings.Contains(u, ":") {
// fix remote before computing repo id
} Try / catch
id, err := beads.ComputeRepoIDForPath(path)
if err != nil && strings.Contains(err.Error(), "failed to canonicalize URL") {
return fmt.Errorf("fix remote: git remote set-url origin <url>: %w", err)
} Prevention
- Keep remotes in standard https:// or git@host:path form
- Inspect `git remote -v` after editing .git/config by hand
- Avoid exotic ext::/helper-based remotes for repos fingerprinted by bd
- Strip whitespace before setting remote URLs
When it happens
Trigger: Calling ComputeRepoIDForPath on a repo whose `git remote get-url` output cannot be canonicalized — e.g. a malformed remote URL, an unparsable scheme, or unusual output from a insteadOf rewrite that canonicalizeGitURL rejects.
Common situations: Hand-edited .git/config with a broken URL; exotic remote helpers (e.g. `ext::` or credential-helper rewritten URLs); typos like `https:/host/repo` (single slash); corporate proxies injecting non-URL values into the remote.
Related errors
- target changed files changed
- target git directory identity changed (contents mismatch)
- registered target identity changed (git marker mismatch)
- not a git repository
- invalid URL: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/68e1c2b6aa604b8f.
Report an issue: GitHub.