{"record":{"id":"57587e9a3bdb6396","repo":"apache/answer","slug":"failed-to-copy-ui-files-w","errorCode":null,"errorMessage":"failed to copy ui files: %w","messagePattern":"failed to copy ui files: %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/cli/build.go","lineNumber":335,"sourceCode":"\t}\n\treturn nil\n}\n\n// copyUIFiles copy ui files from answer module to tmp dir\nfunc copyUIFiles(b *buildingMaterial) (err error) {\n\tgoListCmd := b.newExecCmd(\"go\", \"list\", \"-mod=mod\", \"-m\", \"-f\", \"{{.Dir}}\", \"github.com/apache/answer\")\n\tbuf := new(bytes.Buffer)\n\tgoListCmd.Stdout = buf\n\tif err = goListCmd.Run(); err != nil {\n\t\treturn fmt.Errorf(\"failed to run go list: %w\", err)\n\t}\n\n\tanswerDir := strings.TrimSpace(buf.String())\n\tgoModUIDir := filepath.Join(answerDir, \"ui\")\n\tlocalUIBuildDir := filepath.Join(b.tmpDir, \"vendor/github.com/apache/answer/ui/\")\n\t// The node_modules folder generated during development will interfere packaging, so it needs to be ignored.\n\tif err = copyDirEntries(os.DirFS(goModUIDir), \".\", localUIBuildDir, \"node_modules\"); err != nil {\n\t\treturn fmt.Errorf(\"failed to copy ui files: %w\", err)\n\t}\n\n\tpluginsDir := filepath.Join(b.tmpDir, \"vendor/github.com/apache/answer-plugins/\")\n\tlocalUIPluginDir := filepath.Join(localUIBuildDir, \"src/plugins/\")\n\n\t// copy plugins dir\n\tfmt.Printf(\"try to copy dir from %s to %s\\n\", pluginsDir, localUIPluginDir)\n\n\t// if plugins dir not exist means no plugins\n\tif !dir.CheckDirExist(pluginsDir) {\n\t\treturn nil\n\t}\n\n\tpluginsDirEntries, err := os.ReadDir(pluginsDir)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to read plugins dir: %w\", err)\n\t}\n\tfor _, entry := range pluginsDirEntries {","sourceCodeStart":317,"sourceCodeEnd":353,"githubUrl":"https://github.com/apache/answer/blob/3b9f1370612e690a0b7f230f05e688930db4c6d3/internal/cli/build.go#L317-L353","documentation":"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).","triggerScenarios":"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.","commonSituations":"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.","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)."],"exampleFix":"// before: goModUIDir assumed to exist\nif err = copyDirEntries(os.DirFS(goModUIDir), \".\", localUIBuildDir, \"node_modules\"); err != nil {\n\treturn fmt.Errorf(\"failed to copy ui files: %w\", err)\n}\n// after: pre-check the source dir\nif !dir.CheckDirExist(goModUIDir) {\n\treturn fmt.Errorf(\"answer ui dir not found at %s; run 'go mod download github.com/apache/answer'\", goModUIDir)\n}\nif err = copyDirEntries(os.DirFS(goModUIDir), \".\", localUIBuildDir, \"node_modules\"); err != nil {\n\treturn fmt.Errorf(\"failed to copy ui files: %w\", err)\n}","handlingStrategy":"validation","validationCode":"answerDir, err := exec.Command(\"go\", \"list\", \"-mod=mod\", \"-m\", \"-f\", \"{{.Dir}}\", \"github.com/apache/answer\").Output()\nif err != nil { return fmt.Errorf(\"answer module not in go.mod/cache: %w\", err) }\nuiDir := filepath.Join(strings.TrimSpace(string(answerDir)), \"ui\")\nif st, err := os.Stat(uiDir); err != nil || !st.IsDir() {\n\treturn fmt.Errorf(\"answer ui dir missing at %s; run: go mod download github.com/apache/answer\", uiDir)\n}\nif err := checkWritable(filepath.Dir(localUIBuildDir)); err != nil { return err }","typeGuard":"func dirExistsWritable(p string) bool {\n\tst, err := os.Stat(p)\n\treturn err == nil && st.IsDir()\n}\nfunc checkWritable(dirPath string) error {\n\tprobe := filepath.Join(dirPath, \".write-probe\")\n\tif err := os.WriteFile(probe, nil, 0o600); err != nil { return err }\n\treturn os.Remove(probe)\n}","tryCatchPattern":"err := copyUIFiles(b)\nvar perr *fs.PathError\nif errors.As(err, &perr) {\n\tlog.Printf(\"copy failed on path %s: %v\", perr.Path, perr.Err)\n}\nreturn err","preventionTips":["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."],"tags":["filesystem","go-modules","build","copy"],"backgroundTag":"file-copy-failed","analyzedSha":"3b9f1370612e690a0b7f230f05e688930db4c6d3","analyzedAt":"2026-09-05T18:18:39.533Z","contentChangedAt":"2026-09-05T18:18:39.533Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}