apache/answer · error

failed to clone %s@%s: %w Tip: set ANSWER_MODULE to a local

Error message

failed to clone %s@%s: %w
Tip: set ANSWER_MODULE to a local checkout path instead, e.g. ANSWER_MODULE=/path/to/answer

What it means

resolveAnswerModuleReplacement (v2+ module path) shells out to `git clone --depth=1 --branch=<tag>` to fetch the answer module source; when the clone command exits nonzero it wraps the git error with a Tip suggesting setting ANSWER_MODULE to a local checkout.

Source

Thrown at internal/cli/build.go:293

		return replacement, nil
	}

	// Clone the repo to a local directory and return its path.
	gitURL := "https://" + moduleName
	tag := "v" + strings.TrimPrefix(version, "v")
	localPath := filepath.Join(filepath.Dir(tmpDir), fmt.Sprintf("answer_src_%s", strings.ReplaceAll(version, ".", "_")))

	if _, statErr := os.Stat(localPath); statErr == nil {
		fmt.Printf("[build] using cached local clone at %s\n", localPath)
		return localPath, nil
	}

	fmt.Printf("[build] v2+ module detected, cloning %s@%s to local path %s...\n", moduleName, version, localPath)
	cloneCmd := exec.Command("git", "clone", "--depth=1", "--branch="+tag, gitURL, localPath)
	cloneCmd.Stdout = os.Stdout
	cloneCmd.Stderr = os.Stderr
	if err = cloneCmd.Run(); err != nil {
		return "", fmt.Errorf(
			"failed to clone %s@%s: %w\nTip: set ANSWER_MODULE to a local checkout path instead, e.g. ANSWER_MODULE=/path/to/answer",
			moduleName, version, err,
		)
	}

	fmt.Printf("[build] successfully cloned to %s\n", localPath)
	return localPath, nil
}

// movePluginToVendor move plugin to vendor dir
// Traverse the plugins, and if the plugin path is not github.com/apache/answer-plugins, move the contents of the current plugin to the vendor/github.com/apache/answer-plugins/ directory.
func movePluginToVendor(b *buildingMaterial) (err error) {
	pluginsDir := filepath.Join(b.tmpDir, "vendor/github.com/apache/answer-plugins/")
	for _, p := range b.plugins {
		pluginDir := filepath.Join(b.tmpDir, "vendor/", p.Name)
		pluginName := filepath.Base(p.Name)
		if !strings.HasPrefix(p.Name, "github.com/apache/answer-plugins/") {
			fmt.Printf("try to copy dir from %s to %s\n", pluginDir, filepath.Join(pluginsDir, pluginName))

View on GitHub (pinned to 3b9f137061)

Solutions

  1. Set ANSWER_MODULE to a local checkout of the answer repo, e.g. ANSWER_MODULE=/path/to/answer, to skip cloning.
  2. Check network/proxy settings; test `git clone --depth=1 --branch=<tag> <url>` manually.
  3. Verify the tag/version exists in the answer repository (or use a published version).
  4. Ensure git is installed in the build environment and delete any stale target directory before rebuilding.

Example fix

// before
$ answer build (resolves module by cloning github.com/apache/answer@v2.x)
// after
$ export ANSWER_MODULE=/path/to/local/answer
$ answer build
Defensive patterns

Strategy: fallback

Validate before calling

git --version && git ls-remote --tags https://github.com/apache/answer.git | grep "refs/tags/$TAG" || echo "tag missing or network blocked"

Try / catch

out, err := resolveAnswerModuleReplacement(...)
if err != nil && strings.Contains(err.Error(), "failed to clone") {
  if local := os.Getenv("ANSWER_MODULE"); local != "" {
    out, err = useLocalCheckout(local)
  }
}

Prevention

When it happens

Trigger: `answer build` resolving a v2+ module: git clone fails because the tag doesn't exist, no network/proxy blocking git access, repo URL unreachable, git not installed, or target localPath already exists and is not empty.

Common situations: Building offline/behind corporate proxy, referencing a version tag that hasn't been published, GitHub rate-limit/outage, git missing in CI container images, stale leftover directory from a previous failed build.

Related errors


AI-assisted analysis of apache/answer@3b9f137061 (2026-09-05). Data as JSON: /api/errors/23103aa2fdb9bed5. Report an issue: GitHub.