apache/answer · error
failed to copy ui files: %w
Error message
failed to copy ui files: %w
What it means
copyUIFiles copies the `ui` directory of the downloaded github.com/apache/answer module (located via `go list -m -f {{.Dir}}`) into the build tmp dir at vendor/github.com/apache/answer/ui/, skipping node_modules. This error wraps any failure from copyDirEntries during that copy, typically an OS-level mkdir/open/read/copy failure on either the source (go module cache) or destination (tmp build dir).
Source
Thrown at internal/cli/build.go:335
}
return nil
}
// copyUIFiles copy ui files from answer module to tmp dir
func copyUIFiles(b *buildingMaterial) (err error) {
goListCmd := b.newExecCmd("go", "list", "-mod=mod", "-m", "-f", "{{.Dir}}", "github.com/apache/answer")
buf := new(bytes.Buffer)
goListCmd.Stdout = buf
if err = goListCmd.Run(); err != nil {
return fmt.Errorf("failed to run go list: %w", err)
}
answerDir := strings.TrimSpace(buf.String())
goModUIDir := filepath.Join(answerDir, "ui")
localUIBuildDir := filepath.Join(b.tmpDir, "vendor/github.com/apache/answer/ui/")
// The node_modules folder generated during development will interfere packaging, so it needs to be ignored.
if err = copyDirEntries(os.DirFS(goModUIDir), ".", localUIBuildDir, "node_modules"); err != nil {
return fmt.Errorf("failed to copy ui files: %w", err)
}
pluginsDir := filepath.Join(b.tmpDir, "vendor/github.com/apache/answer-plugins/")
localUIPluginDir := filepath.Join(localUIBuildDir, "src/plugins/")
// copy plugins dir
fmt.Printf("try to copy dir from %s to %s\n", pluginsDir, localUIPluginDir)
// if plugins dir not exist means no plugins
if !dir.CheckDirExist(pluginsDir) {
return nil
}
pluginsDirEntries, err := os.ReadDir(pluginsDir)
if err != nil {
return fmt.Errorf("failed to read plugins dir: %w", err)
}
for _, entry := range pluginsDirEntries {View on GitHub (pinned to 3b9f137061)
Solutions
- Verify the answer module ui dir exists: run `go list -m -mod=mod -f {{.Dir}} github.com/apache/answer` and check `<dir>/ui` exists; if missing, run `go mod download github.com/apache/answer` or clear the module cache (`go clean -modcache`) and re-download.
- Check write permissions and free space on the build tmp dir; re-run the build with a writable --tmp-dir / as a user that owns it.
- Remove a stale/partial tmp build directory from an earlier failed build so directories can be created cleanly.
- Re-run with the wrapped underlying error (the %w cause) to identify which file failed and fix the specific path (e.g. restore/delete it).
Example fix
// before: goModUIDir assumed to exist
if err = copyDirEntries(os.DirFS(goModUIDir), ".", localUIBuildDir, "node_modules"); err != nil {
return fmt.Errorf("failed to copy ui files: %w", err)
}
// after: pre-check the source dir
if !dir.CheckDirExist(goModUIDir) {
return fmt.Errorf("answer ui dir not found at %s; run 'go mod download github.com/apache/answer'", goModUIDir)
}
if err = copyDirEntries(os.DirFS(goModUIDir), ".", localUIBuildDir, "node_modules"); err != nil {
return fmt.Errorf("failed to copy ui files: %w", err)
} Defensive patterns
Strategy: validation
Validate before calling
answerDir, err := exec.Command("go", "list", "-mod=mod", "-m", "-f", "{{.Dir}}", "github.com/apache/answer").Output()
if err != nil { return fmt.Errorf("answer module not in go.mod/cache: %w", err) }
uiDir := filepath.Join(strings.TrimSpace(string(answerDir)), "ui")
if st, err := os.Stat(uiDir); err != nil || !st.IsDir() {
return fmt.Errorf("answer ui dir missing at %s; run: go mod download github.com/apache/answer", uiDir)
}
if err := checkWritable(filepath.Dir(localUIBuildDir)); err != nil { return err } Type guard
func dirExistsWritable(p string) bool {
st, err := os.Stat(p)
return err == nil && st.IsDir()
}
func checkWritable(dirPath string) error {
probe := filepath.Join(dirPath, ".write-probe")
if err := os.WriteFile(probe, nil, 0o600); err != nil { return err }
return os.Remove(probe)
} Try / catch
err := copyUIFiles(b)
var perr *fs.PathError
if errors.As(err, &perr) {
log.Printf("copy failed on path %s: %v", perr.Path, perr.Err)
}
return err Prevention
- Run `go mod download github.com/apache/answer` before building to guarantee the ui dir exists in the module cache.
- Always build with a writable, dedicated tmp dir owned by the build user.
- Clean stale tmp build dirs between builds (the tooling does not always clean up).
- Monitor disk space/quota on the build volume.
- Keep the Go module cache on a local (not read-only/network) mount.
When it happens
Trigger: copyDirEntries(os.DirFS(goModUIDir), ".", localUIBuildDir, "node_modules") fails because goModUIDir (answer module's ui/ dir in the module cache) is missing/unreadable, the tmp destination cannot be created or written (permissions, disk full, path taken by a file), or an individual file open/copy inside the walk fails.
Common situations: Go module cache corrupted or answer module not fully downloaded (GOFLAGS -mod=mod fetching issues); running the build in a container/user without write permission to tmpDir; disk quota exceeded; a previous failed build left a file where a directory must be created; custom GOPATH/module cache on a read-only mount.
Related errors
- failed to read plugins dir: %w
- failed to create directory %s: %w
- failed to open source file %s: %w
- failed to create destination file %s: %w
- failed to clone %s@%s: %w Tip: set ANSWER_MODULE to a local
AI-assisted analysis of apache/answer@3b9f137061 (2026-09-05).
Data as JSON: /api/errors/57587e9a3bdb6396.
Report an issue: GitHub.