apache/answer · error

failed to create destination file %s: %w

Error message

failed to create destination file %s: %w

What it means

Returned by the copy helper in internal/cli/build.go when os.Create(dstPath) fails after the source file was opened successfully. os.Create fails when the destination directory does not exist, the process lacks write permission, dstPath is a directory, or the path is invalid for the OS. The wrapped %w error carries the exact OS reason.

Source

Thrown at internal/cli/build.go:543

		if d.IsDir() {
			// Create the directory in the destination
			err := os.MkdirAll(dstPath, os.ModePerm)
			if err != nil {
				return fmt.Errorf("failed to create directory %s: %w", dstPath, err)
			}
		} else {
			// Open the source file
			srcFile, err := sourceFs.Open(srcPath)
			if err != nil {
				return fmt.Errorf("failed to open source file %s: %w", srcPath, err)
			}
			defer srcFile.Close()

			// Create the destination file
			dstFile, err := os.Create(dstPath)
			if err != nil {
				return fmt.Errorf("failed to create destination file %s: %w", dstPath, err)
			}
			defer dstFile.Close()

			// Copy the file contents
			_, err = io.Copy(dstFile, srcFile)
			if err != nil {
				return fmt.Errorf("failed to copy file contents from %s to %s: %w", srcPath, dstPath, err)
			}
		}

		return nil
	})

	return err
}

// format plugins dir name from dash to underline
func formatUIPluginsDirName(dirPath string) {

View on GitHub (pinned to 3b9f137061)

Solutions

  1. Read the wrapped OS error: 'no such file or directory' means a parent dir is missing; 'permission denied' means fix ownership/chmod
  2. Ensure os.MkdirAll(filepath.Dir(dstPath), os.ModePerm) is called before os.Create for every file
  3. Check that targetDir exists and is writable by the process user (ls -ld, or touch a test file)
  4. Verify dstPath is not itself an existing directory

Example fix

// before
dstFile, err := os.Create(dstPath)
// after
if err := os.MkdirAll(filepath.Dir(dstPath), os.ModePerm); err != nil {
    return fmt.Errorf("failed to create directory %s: %w", filepath.Dir(dstPath), err)
}
dstFile, err := os.Create(dstPath)
Defensive patterns

Strategy: validation

Validate before calling

// ensure destination parent exists and is writable before creating the file
if err := os.MkdirAll(filepath.Dir(dstPath), os.ModePerm); err != nil {
    return err
}
if info, err := os.Stat(filepath.Dir(dstPath)); err != nil || !info.IsDir() {
    return fmt.Errorf("destination dir %s not writable", filepath.Dir(dstPath))
}

Try / catch

dstFile, err := os.Create(dstPath)
if err != nil {
    var perr *fs.PathError
    if errors.As(err, &perr) && errors.Is(perr.Err, syscall.EACCES) {
        log.Printf("permission denied creating %s — check ownership/uid in container", dstPath)
    }
    return err
}

Prevention

When it happens

Trigger: dstPath = filepath.Join(targetDir, path) where targetDir's parent directories were not created (MkdirAll only creates directories for walked dirs, and a skipped ignoreThisDir dir can leave parents missing), targetDir is read-only, or dstPath collides with an existing directory.

Common situations: Deploying UI/plugin assets into a target dir owned by another user; running the binary in a container with a read-only mount; ignore rules excluding a parent directory so its children's destination folders never get created.

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


AI-assisted analysis of apache/answer@3b9f137061 (2026-09-05). Data as JSON: /api/errors/f1520dd80a009116. Report an issue: GitHub.