Tencent/WeKnora · error

failed to open file: %w

Error message

failed to open file: %w

What it means

SaveFile wraps the error from file.Open() (the multipart/form-data uploaded file handle) when the uploaded file cannot be opened for reading. The original OS error is preserved via %w so callers can inspect os/fs error types. It indicates the upload's in-memory temp file handle is no longer readable.

Source

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

	}
	logger.Infof(ctx, "Creating directory: %s", dir)
	if err := os.MkdirAll(dir, 0o755); err != nil {
		logger.Errorf(ctx, "Failed to create directory: %v", err)
		return "", fmt.Errorf("failed to create directory: %w", err)
	}

	// Generate unique filename using timestamp
	ext := filepath.Ext(file.Filename)
	filename := fmt.Sprintf("%d%s", time.Now().UnixNano(), ext)
	filePath := filepath.Join(dir, filename)
	logger.Infof(ctx, "Generated file path: %s", filePath)

	// Open source file for reading
	logger.Info(ctx, "Opening source file")
	src, err := file.Open()
	if err != nil {
		logger.Errorf(ctx, "Failed to open source file: %v", err)
		return "", fmt.Errorf("failed to open file: %w", err)
	}
	defer src.Close()

	// Create destination file for writing
	logger.Info(ctx, "Creating destination file")
	dst, err := os.Create(filePath)
	if err != nil {
		logger.Errorf(ctx, "Failed to create destination file: %v", err)
		return "", fmt.Errorf("failed to create file: %w", err)
	}
	defer dst.Close()

	// Copy content from source to destination
	logger.Info(ctx, "Copying file content")
	if _, err := io.Copy(dst, src); err != nil {
		logger.Errorf(ctx, "Failed to copy file content: %v", err)
		return "", fmt.Errorf("failed to save file: %w", err)
	}

View on GitHub (pinned to 988cbb0330)

Solutions

  1. Check that the request context / multipart form is still valid and the body has not been consumed before calling SaveFile
  2. Raise the file-descriptor limit (ulimit -n) or reduce concurrent uploads if the log shows 'too many open files'
  3. Retry the upload from the client if a disconnect is suspected
  4. Inspect the wrapped error with errors.As for *fs.PathError / syscall errors to pick the right fix

Example fix

// before
src, err := file.Open()
if err != nil {
	return "", fmt.Errorf("failed to open file: %w", err)
}
// after: verify the handle early and surface a clearer message
src, err := file.Open()
if err != nil {
	logger.Errorf(ctx, "uploaded file unreadable (client disconnect?): %v", err)
	return "", fmt.Errorf("failed to open uploaded file: %w", err)
}
Defensive patterns

Strategy: try-catch

Try / catch

src, err := fileHeader.Open()
if err != nil {
	if errors.Is(err, fs.ErrNotExist) {
		// multipart temp file gone: ask client to re-upload
	}
	return fmt.Errorf("failed to open file: %w", err)
}

Prevention

When it happens

Trigger: Calling SaveFile with a *multipart.FileHeader whose Open() fails: the underlying temp file was deleted, the multipart form was consumed/closed before this call, too many open files (EMFILE), or the request body was already drained/aborted by the client.

Common situations: Client disconnects mid-upload so the server temp file vanishes; server hits the OS file-descriptor limit under load; middleware closes the request body before the handler saves the file; disk cleanup removes multipart temp files.

Understand the failure class

Background: "open() failed", "failed to open file", "cannot create file" — what a file open error means and how to fix it — this error's family across 42 libraries.

Related errors


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