flipped-aurora/gin-vue-admin · error

创建编译目录失败: %w

Error message

创建编译目录失败: %w

What it means

After creating the build root, compileCliBinary allocates a per-build temp directory with os.MkdirTemp(absBuildRoot, "cli-"). Failure here (wrapped in this error) means a new temp subdir could not be created even though the root exists — typically a race, permission change, or filesystem full condition.

Source

Thrown at server/plugin/ai/service/sys_cli_build.go:94

	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"
	}
	binaryName += cliBinaryExt(goos)
	binaryPath := filepath.Join(buildDir, binaryName)

	if err := runGoBuild(buildDir, binaryPath, goos, goarch); err != nil {

View on GitHub (pinned to 3136500ef3)

Solutions

  1. Check disk space and inodes (df -h / df -i) on the volume holding the build dir and free space
  2. Clean up stale cli-* directories left by crashed builds
  3. Ensure no external cleanup job deletes the build root while builds run; scope cleanup to old dirs only
  4. Grant the server user write permission on the build root again if it changed
  5. If a previous build crashed, note MkdirTemp dirs are removed via defer os.RemoveAll only on clean returns — sweep orphans periodically

Example fix

# find and remove orphaned build dirs older than a day
find /var/lib/gva/cli-build -maxdepth 1 -name 'cli-*' -mtime +1 -exec rm -rf {} +
Defensive patterns

Strategy: retry

Validate before calling

if st, err := os.Stat(cliBuildDir); err != nil || !st.IsDir() {
    return errors.New("build root missing or not a directory")
}

Try / catch

bin, content, err := svc.BuildCliBinary(cli, manifest, goos, goarch)
if err != nil {
    if strings.Contains(err.Error(), "创建编译目录失败") && isTransient(err) {
        time.Sleep(500 * time.Millisecond)
        return svc.BuildCliBinary(cli, manifest, goos, goarch) // one retry
    }
    return err
}

Prevention

When it happens

Trigger: Disk full or inode exhaustion on the partition holding absBuildRoot; permissions changed on the build root between MkdirAll and MkdirTemp; concurrent cleanup scripts deleting the root mid-build; quota limits on the volume.

Common situations: Long-running servers whose build dir filled up with stale cli-* temp dirs; monitoring jobs or cron cleaning the build root while a build is in flight; small tmpfs volume allocated for the build directory.

Related errors


AI-assisted analysis of flipped-aurora/gin-vue-admin@3136500ef3 (2026-08-31). Data as JSON: /api/errors/3243039e380d17db. Report an issue: GitHub.