Tencent/WeKnora · error

failed to create file: %w

Error message

failed to create file: %w

What it means

SaveFile wraps the error from os.Create(filePath) when the destination file under the storage base directory cannot be created. This is a write-side filesystem error: the wrapped error carries the exact path and reason. The destination is never created in this case.

Source

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

	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)
	}

	logger.Infof(ctx, "File saved successfully: %s", filePath)
	// Return provider:// path format: local://{relative_path}
	relPath, _ := filepath.Rel(s.baseDir, filePath)
	return localScheme + filepath.ToSlash(relPath), nil
}

// GetFile retrieves a file from the local file system by its path
// Returns a ReadCloser for reading the file content

View on GitHub (pinned to 988cbb0330)

Solutions

  1. Ensure the storage directory exists and is writable by the service user (mkdir -p and chown the baseDir)
  2. Verify LOCAL_STORAGE_BASE_DIR is correct and mounted (not read-only) in the deployment environment
  3. Check disk space with df and clean up or expand the volume if full
  4. Inspect the wrapped *fs.PathError path to confirm which directory is the problem

Example fix

// before service construction
svc := file.NewLocalService(cfg.BaseDir)
// after: fail fast at startup if the base dir is unusable
if err := os.MkdirAll(cfg.BaseDir, 0o755); err != nil {
	log.Fatalf("storage base dir unusable: %v", err)
}
Defensive patterns

Strategy: validation

Validate before calling

info, err := os.Stat(baseDir)
if err != nil || !info.IsDir() {
	return fmt.Errorf("storage base dir %q missing", baseDir)
}
if info.Mode().Perm()&0o200 == 0 {
	return fmt.Errorf("storage base dir %q not writable", baseDir)
}

Try / catch

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

Prevention

When it happens

Trigger: os.Create fails because the directory under baseDir does not exist, the process lacks write permission on it, the disk is full, the path component is invalid, or baseDir itself was misconfigured to a non-existent/unwritable location.

Common situations: LOCAL_STORAGE_BASE_DIR pointing at a read-only volume or path that was never mkdir'd; container running as non-root user without ownership of the storage volume; disk quota/full-disk in production; SELinux/apparmor blocking writes.

Related errors


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