flipped-aurora/gin-vue-admin · error

读取 CLI 源码目录失败(%s): %w

Error message

读取 CLI 源码目录失败(%s): %w

What it means

copyCliSources copies the gva CLI source directory (cliSourceDir) into the per-build temp directory, skipping tests and embedded.go. It first reads the source dir with os.ReadDir; if that fails, this error wrapping the OS error is returned. It means the embedded/reference source tree shipped with the deployment is missing or unreadable.

Source

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

	}
	binaryName += cliBinaryExt(goos)
	binaryPath := filepath.Join(buildDir, binaryName)

	if err := runGoBuild(buildDir, binaryPath, goos, goarch); err != nil {
		return "", nil, err
	}
	binary, err := os.ReadFile(binaryPath)
	if err != nil {
		return "", nil, err
	}
	return binaryName, binary, nil
}

// copyCliSources 复制 gva 源码到编译目录,跳过测试文件和默认的 embedded.go。
func copyCliSources(srcDir, destDir string) error {
	entries, err := os.ReadDir(srcDir)
	if err != nil {
		return fmt.Errorf("读取 CLI 源码目录失败(%s): %w", srcDir, err)
	}
	for _, entry := range entries {
		if entry.IsDir() {
			continue
		}
		name := entry.Name()
		if !strings.HasSuffix(name, ".go") || strings.HasSuffix(name, "_test.go") {
			continue
		}
		if name == cliEmbeddedGoName {
			continue
		}
		data, err := os.ReadFile(filepath.Join(srcDir, name))
		if err != nil {
			return err
		}
		if err := os.WriteFile(filepath.Join(destDir, name), data, 0o644); err != nil {
			return err

View on GitHub (pinned to 3136500ef3)

Solutions

  1. Verify cliSourceDir exists and is readable by the server user (ls -la) and fix the deployment package
  2. Check the server's working directory — if cliSourceDir is relative, an unexpected cwd breaks resolution; set an absolute path
  3. Re-deploy including the CLI source assets in the image/artifact
  4. Fix permissions (chown/chmod) if the dir exists but is unreadable

Example fix

// before (dockerfile)
COPY server/gva ./gva
// after — include the CLI source dir
COPY server/gva ./gva
COPY server/resource/cli-source ./gva/resource/cli-source
Defensive patterns

Strategy: validation

Validate before calling

if st, err := os.Stat(cliSourceDir); err != nil || !st.IsDir() {
    return fmt.Errorf("CLI source dir %s missing or unreadable", cliSourceDir)
}

Try / catch

bin, content, err := svc.BuildCliBinary(cli, manifest, goos, goarch)
if err != nil {
    if strings.Contains(err.Error(), "读取 CLI 源码目录失败") {
        return nil, fmt.Errorf("deployment incomplete: CLI sources missing at %s", cliSourceDir)
    }
    return err
}

Prevention

When it happens

Trigger: cliSourceDir was not shipped (Docker image built without it), was deleted by a cleanup job, or the server process lacks read permission on it. Triggered from BuildCliBinary/BuildCliSkill via compileCliBinary.

Common situations: Packaging the binary alone without the server/resource directories; container images that exclude source assets; wrong working directory so the relative cliSourceDir resolves to a nonexistent path; restrictive file modes after extraction as root.

Related errors


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