gastownhall/beads · error

%w Output: %s

Error message

%w
Output: %s

What it means

doltClone() runs `dolt clone <remoteURL> <target>` and, on non-zero exit, returns the exec error wrapped together with dolt's combined stdout/stderr. This is the cold-start path of Ensure(): the remote could not be cloned into the local cache. The embedded Output text contains dolt's actual reason.

Source

Thrown at internal/remotecache/cache.go:195

// Evict removes a cached remote clone entirely.
func (c *Cache) Evict(remoteURL string) error {
	entry := c.entryDir(remoteURL)
	return os.RemoveAll(entry)
}

// doltExists checks if a dolt database exists at the given path.
func (c *Cache) doltExists(dbPath string) bool {
	doltDir := filepath.Join(dbPath, ".dolt")
	info, err := os.Stat(doltDir)
	return err == nil && info.IsDir()
}

// doltClone clones a remote into the target directory.
func (c *Cache) doltClone(ctx context.Context, remoteURL, target string) error {
	cmd := doltCmd(ctx, "", doltCloneArgs(remoteURL, target)...)
	if output, err := cmd.CombinedOutput(); err != nil {
		return fmt.Errorf("%w\nOutput: %s", err, output)
	}
	return nil
}

// doltCmd builds a dolt CLI invocation for cache transfers with git tracing
// scrubbed (internal/gittraceenv) and templated hooks disabled (GH#4272).
// dir "" runs in the process working directory.
func doltCmd(ctx context.Context, dir string, args ...string) *exec.Cmd {
	cmd := exec.CommandContext(ctx, "dolt", args...) // #nosec G204 -- fixed command with validated remote/ref args
	cmd.Dir = dir
	cmd.Env = githooksenv.DisabledEnv(gittraceenv.ScrubEnv(os.Environ()))
	return cmd
}

func doltCloneArgs(remoteURL, target string) []string {
	args := []string{"clone"}
	if user := os.Getenv("DOLT_REMOTE_USER"); user != "" {
		args = append(args, "--user", user)

View on GitHub (pinned to 71377f2769)

Solutions

  1. Read the wrapped `Output:` lines — dolt's message names the real cause (auth, DNS, not found).
  2. Validate the URL: it must pass remotecache.ValidateRemoteURL (e.g. dolthub://org/repo, https://...).
  3. Set credentials: DOLT_REMOTE_USER/DOLT_REMOTE_PASSWORD env vars or `dolt creds use`.
  4. Confirm network reachability and proxy settings; test `dolt clone <url> /tmp/test` manually.
  5. Free disk space / fix permissions on the cache dir; if the target exists but is broken, Evict() then retry.

Example fix

// before: passing a bare repo name without scheme
_, err := cache.Ensure(ctx, "myorg/myrepo")
// after: fully qualified URL
_, err := cache.Ensure(ctx, "dolthub://myorg/myrepo")
Defensive patterns

Strategy: try-catch

Validate before calling

if err := remotecache.ValidateRemoteURL(remoteURL); err != nil {
    return fmt.Errorf("bad remote URL %q: %w", remoteURL, err)
}
if _, err := exec.LookPath("dolt"); err != nil {
    return fmt.Errorf("dolt CLI not installed")
}
if os.Getenv("DOLT_REMOTE_USER") == "" {
    fmt.Fprintln(os.Stderr, "warning: DOLT_REMOTE_USER unset; private remotes will fail to clone")
}

Try / catch

if _, err := cache.Ensure(ctx, url); err != nil {
    if strings.Contains(err.Error(), "dolt clone failed") {
        // surface dolt's own output to the operator
        return fmt.Errorf("cannot reach or authenticate to %s: %w", url, err)
    }
    return err
}

Prevention

When it happens

Trigger: Cache.Ensure() on a machine with no cached clone invokes doltClone; dolt exits non-zero because the remote URL is wrong/unreachable, authentication is missing (DOLT_REMOTE_USER/DOLT_REMOTE_PASSWORD/dolt creds), the target path is unwritable, or the dolt CLI version is incompatible with the remote.

Common situations: First sync on a new machine; typos or unsupported schemes in the remote URL; corporate proxy/firewall blocking Dolthub; expired credentials; full disk or permission-denied cache dir; remote repo deleted or made private.

Related errors


AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30). Data as JSON: /api/errors/597648d96c30a3de. Report an issue: GitHub.