flipped-aurora/gin-vue-admin · error
创建编译根目录失败: %w
Error message
创建编译根目录失败: %w
What it means
compileCliBinary creates the CLI build root directory with os.MkdirAll(absBuildRoot, 0o755). If directory creation fails — permission denied, parent path is a file, read-only filesystem, or disk issues — this wrapped error is returned. The build cannot proceed without a writable build root.
Source
Thrown at server/plugin/ai/service/sys_cli_build.go:89
applyCliBuildBaseURL(&manifest, req.BaseURL)
manifestBytes, err := marshalSysCliManifest(manifest)
if err != nil {
return "", nil, err
}
return s.compileCliBinary(cli, manifestBytes, goos, goarch)
}
// compileCliBinary 把 manifest 内嵌进 gva 源码副本并交叉编译,返回二进制文件名与内容。
func (s *cliService) compileCliBinary(cli autoModel.SysCli, manifestBytes []byte, goos, goarch string) (string, []byte, error) {
if _, err := exec.LookPath("go"); err != nil {
return "", nil, fmt.Errorf("服务器未安装 Go 工具链,无法编译: %w", err)
}
absBuildRoot, err := filepath.Abs(cliBuildDir)
if err != nil {
return "", nil, fmt.Errorf("解析编译目录失败: %w", err)
}
if err := os.MkdirAll(absBuildRoot, 0o755); err != nil {
return "", nil, fmt.Errorf("创建编译根目录失败: %w", err)
}
buildDir, err := os.MkdirTemp(absBuildRoot, "cli-")
if err != nil {
return "", nil, fmt.Errorf("创建编译目录失败: %w", err)
}
defer os.RemoveAll(buildDir)
if err := copyCliSources(cliSourceDir, buildDir); err != nil {
return "", nil, err
}
if err := writeEmbeddedManifest(buildDir, manifestBytes); err != nil {
return "", nil, err
}
binaryName := sanitizeSingleSegmentSlug(cli.Command)
if binaryName == "" {
binaryName = "cli"View on GitHub (pinned to 3136500ef3)
Solutions
- chown/chmod the build root so the server process user can write (e.g. mkdir -p <dir> && chown <user> <dir>)
- Mount a writable volume at the build dir in container/K8s deployments
- Point cliBuildDir at a guaranteed-writable location (e.g. /tmp or a data volume) via config
- Check nothing occupies the path as a regular file (ls -la the parent and remove/rename the file)
Example fix
// before (dockerfile, read-only root) // no volume for build dir // after VOLUME ["/data/gva-cli-build"] ENV GVA_CLI_BUILD_DIR=/data/gva-cli-build
Defensive patterns
Strategy: validation
Validate before calling
probe := filepath.Join(cliBuildDir, ".write-test")
if err := os.WriteFile(probe, nil, 0o644); err != nil {
return fmt.Errorf("build dir not writable: %w", err)
}
os.Remove(probe) Try / catch
bin, content, err := svc.BuildCliBinary(cli, manifest, goos, goarch)
if err != nil {
if strings.Contains(err.Error(), "创建编译根目录失败") {
return nil, fmt.Errorf("build root %s not writable: check permissions/read-only FS", cliBuildDir)
}
return err
} Prevention
- Mount a writable volume at the build dir in containers/K8s
- chown the build dir to the server process user after deployment
- Keep cliBuildDir off read-only root filesystems
When it happens
Trigger: Running the server as a non-root user without write permission on the cliBuildDir path; cliBuildDir (or a parent) exists as a regular file; deploying with a read-only root filesystem (e.g. Kubernetes readonlyRootFilesystem or read-only Docker volume).
Common situations: Container hardening with read-only FS and no emptyDir/writable volume mounted at the build dir; directory created previously by root and now the service runs as an unprivileged user; path collision where a file named like the build dir exists.
Understand the failure class
Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.
Related errors
- function os.Create() failed, err:
- 文件删除失败:
- function os.ReadDir() failed, err:
- 删除新建文件 %s 失败: %w
- 设置临时文件权限失败: %w
AI-assisted analysis of flipped-aurora/gin-vue-admin@3136500ef3 (2026-08-31).
Data as JSON: /api/errors/a89ab9fe6ca9aad0.
Report an issue: GitHub.