Tencent/WeKnora · error

failed to create destination file: %w

Error message

failed to create destination file: %w

What it means

CopyFile fails to create the destination file at dstPath (<dir>/<unixNano><ext>) via os.Create. The directory was successfully created, but creating the file inside it failed — typically due to permissions, disk-full, or a name/path problem (e.g. dstPath became too long).

Source

Thrown at internal/application/service/file/local.go:201

		return "", fmt.Errorf("invalid path: %w", err)
	}
	if err := os.MkdirAll(dir, 0o755); err != nil {
		return "", fmt.Errorf("failed to create directory: %w", err)
	}

	ext := filepath.Ext(srcPath)
	filename := fmt.Sprintf("%d%s", time.Now().UnixNano(), ext)
	dstPath := filepath.Join(dir, filename)

	src, err := os.Open(srcResolved)
	if err != nil {
		return "", fmt.Errorf("failed to open source file: %w", err)
	}
	defer src.Close()

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

	if _, err := io.Copy(dst, src); err != nil {
		return "", fmt.Errorf("failed to copy file content: %w", err)
	}

	relPath, _ := filepath.Rel(s.baseDir, dstPath)
	newPath := localScheme + filepath.ToSlash(relPath)
	logger.Infof(ctx, "Copied local file %s to %s", srcPath, newPath)
	return newPath, nil
}

// SaveBytes saves bytes data to a file and returns the file path
// temp parameter is ignored for local storage (no auto-expiration support)
// fileName 仅允许安全文件名,禁止路径遍历(如 ../../)
func (s *localFileService) SaveBytes(ctx context.Context, data []byte, tenantID uint64, fileName string, temp bool) (string, error) {
	logger.Infof(ctx, "Saving bytes data: fileName=%s, size=%d, tenantID=%d, temp=%v", fileName, len(data), tenantID, temp)

View on GitHub (pinned to 988cbb0330)

Solutions

  1. Read the wrapped error: EDQUOT/ENOSPC → free space or raise quota on the volume; EACCES → fix directory write permissions.
  2. Check disk usage (`df -h`) on the volume backing s.baseDir and clean up or expand storage.
  3. Sanitize/limit the file extension (filepath.Ext of srcPath) so the generated filename stays within NAME_MAX.
  4. If baseDir is on a read-only mount, reconfigure storage to a writable persistent volume.

Example fix

// before
ext := filepath.Ext(srcPath)
filename := fmt.Sprintf("%d%s", time.Now().UnixNano(), ext)
// after
ext := filepath.Ext(srcPath)
if len(ext) > 16 {
    ext = ext[:16]
}
filename := fmt.Sprintf("%d%s", time.Now().UnixNano(), ext)
Defensive patterns

Strategy: validation

Validate before calling

func ensureDestWritable(dir string) error {
    if fi, err := os.Stat(dir); err != nil || !fi.IsDir() {
        return fmt.Errorf("dest dir invalid: %w", err)
    }
    probe := filepath.Join(dir, ".probe")
    if err := os.WriteFile(probe, []byte{0}, 0o600); err != nil {
        return fmt.Errorf("dest not writable: %w", err)
    }
    os.Remove(probe)
    return nil
}
// also check disk space: syscall.Statfs(dir) → Bavail* Bsize > needed bytes

Try / catch

newPath, err := svc.CopyFile(ctx, srcPath, tenantID, knowledgeID)
if err != nil {
    var perr *fs.PathError
    if errors.As(err, &perr) {
        switch {
        case errors.Is(perr.Err, syscall.ENOSPC), errors.Is(perr.Err, syscall.EDQUOT):
            return fmt.Errorf("storage full: %w", err) // trigger cleanup/expand volume
        case errors.Is(perr.Err, syscall.EACCES):
            return fmt.Errorf("permission denied on storage: %w", err)
        }
    }
    return fmt.Errorf("copy failed: %w", err)
}

Prevention

When it happens

Trigger: Destination directory lacks write permission for the process; filesystem is full or read-only (quota exceeded); dstPath exceeds the filesystem NAME_MAX because a very long file extension inflates the generated name; SELinux/AppArmor policy blocks creation.

Common situations: Disk quota exhausted on the storage volume (common in CI and containers); read-only root filesystem with baseDir inside it; long knowledgeID plus long extension pushing path over 255-byte component limit; misconfigured security profiles blocking writes.

Related errors


AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02). Data as JSON: /api/errors/fba452f7b2595e8a. Report an issue: GitHub.