{"record":{"id":"4d812f0679cd1c81","repo":"gastownhall/beads","slug":"peer-remote-q-uses-git-protocol-and-requires-cli","errorCode":null,"errorMessage":"peer remote %q uses git protocol and requires CLI routing: %w","messagePattern":"peer remote %q uses git protocol and requires CLI routing: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/dolt/federation.go","lineNumber":640,"sourceCode":"// before routing.\nfunc (s *DoltStore) prepareCLIRouteForPeerGitProtocol(ctx context.Context, peer string) (bool, error) {\n\tif s.CLIDir() == \"\" {\n\t\treturn false, nil\n\t}\n\tif !s.hasCLIDatabase() {\n\t\treturn false, nil\n\t}\n\tremotes, err := s.ListRemotes(ctx)\n\tif err != nil {\n\t\treturn false, fmt.Errorf(\"list Dolt remotes before git-protocol routing for peer %q: %w\", peer, err)\n\t}\n\tfor _, r := range remotes {\n\t\tif r.Name == peer {\n\t\t\tif !doltutil.IsGitProtocolURL(r.URL) {\n\t\t\t\treturn false, nil\n\t\t\t}\n\t\t\tif err := s.ensureMatchingCLIRemote(peer, r.URL); err != nil {\n\t\t\t\treturn false, fmt.Errorf(\"peer remote %q uses git protocol and requires CLI routing: %w\", peer, err)\n\t\t\t}\n\t\t\treturn true, nil\n\t\t}\n\t}\n\treturn false, nil\n}\n\nfunc (s *DoltStore) shouldUseCLIForPeerGitProtocol(ctx context.Context, peer string) (bool, error) {\n\treturn s.prepareCLIRouteForPeerGitProtocol(ctx, peer)\n}\n\n// doltCLIPushRefToPeer shells out to `dolt push` with a specific refspec.\n// The refspec can be a branch name or a \"local:remote\" mapping.\nfunc (s *DoltStore) doltCLIPushRefToPeer(ctx context.Context, peer string, refspec string, creds *remoteCredentials) error {\n\tif err := s.prePushFSCK(ctx); err != nil {\n\t\treturn err\n\t}\n\tcmd, transferCtx, cancel := s.prepareDoltCLITransfer(ctx, peer, creds, \"push\", peer, refspec)","sourceCodeStart":622,"sourceCodeEnd":658,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/dolt/federation.go#L622-L658","documentation":"Wraps a failure from s.ensureMatchingCLIRemote after detecting that the peer's Dolt remote URL uses git protocol. The store must mirror the remote in the CLI database so pushes/pulls can be routed through the dolt CLI; if that mirror creation/update fails, git-protocol routing cannot proceed.","triggerScenarios":"prepareCLIRouteForPeerGitProtocol finds the peer remote in ListRemotes output, IsGitProtocolURL(r.URL) is true, and ensureMatchingCLIRemote(peer, r.URL) fails to create or update the matching remote in the CLI database (CLI error, permission, invalid URL).","commonSituations":"Peer URL points to an unreachable or misconfigured git remote; CLI database is read-only; dolt CLI cannot authenticate to the git remote; stale remote entry with a conflicting URL in the CLI database.","solutions":["Run `dolt remote add <peer> <url>` manually in the CLI database dir to see the CLI error","Verify the peer git URL is reachable and credentials (SSH key/token) are configured","Remove any stale conflicting remote entry in the CLI database and retry","Confirm the dolt CLI version supports the git-protocol remote URL scheme used"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"for _, u := range []string{peerURL} {\n\tparsed, err := url.Parse(u)\n\tif err != nil || parsed.Scheme == \"\" { return fmt.Errorf(\"invalid peer remote URL %q\", u) }\n}\nif err := exec.Command(\"git\", \"ls-remote\", peerURL).Run(); err != nil {\n\treturn fmt.Errorf(\"peer git remote unreachable: %w\", err)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Validate peer URLs are reachable before configuring federation","Keep SSH keys/tokens for git remotes current","Clear stale conflicting remotes from the CLI database"],"tags":["dolt","cli","git-protocol","remote","federation"],"backgroundTag":"dolt-cli-remote-setup-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}