gofr-dev/gofr · error
source and destination are the same
Error message
source and destination are the same
What it means
errSameSourceAndDest is returned by CopyObject when the source and destination names are identical. Copying an object onto itself is a no-op at best and data loss at worst, so the adapter rejects it up front.
Source
Thrown at pkg/gofr/datasource/file/ftp/storage_adapter.go:24
"errors"
"fmt"
"io"
"path"
"strings"
"time"
"github.com/jlaffaye/ftp"
"gofr.dev/pkg/gofr/datasource/file"
)
var (
// Storage adapter errors.
errFTPConfigNil = errors.New("FTP config is nil")
errFTPClientNotInitialized = errors.New("FTP client is not initialized")
errEmptyObjectName = errors.New("object name is empty")
errInvalidOffset = errors.New("invalid offset: must be >= 0")
errEmptySourceOrDest = errors.New("source and destination names cannot be empty")
errSameSourceAndDest = errors.New("source and destination are the same")
errFailedToCreateReader = errors.New("failed to create reader")
errFailedToCreateWriter = errors.New("failed to create writer")
errObjectNotFound = errors.New("object not found")
errFailedToGetObjectAttrs = errors.New("failed to get object attrs")
errFailedToDeleteObject = errors.New("failed to delete object")
errFailedToListObjects = errors.New("failed to list objects")
errFailedToListDirectory = errors.New("failed to list directory")
errWriterAlreadyClosed = errors.New("writer already closed")
errFTPConfigInvalid = errors.New("invalid FTP configuration: host and port are required")
)
// Config represents the FTP configuration.
type Config struct {
Host string // FTP server hostname
User string // FTP username
Password string // FTP password
Port int // FTP port
RemoteDir string // Remote directory path. Base Path for all FTP Operations.View on GitHub (pinned to 187eb24962)
Solutions
- Compare src and dst before copying and skip the call (or return a friendly no-op) when they match.
- Ensure rename flows generate a genuinely different destination name.
- Normalize names (path cleaning, case) so identical logical paths compare equal before deciding to copy.
Example fix
// before
err := adapter.CopyObject(ctx, oldName, newName) // newName == oldName
// after
if oldName == newName {
return nil // nothing to do
}
err := adapter.CopyObject(ctx, oldName, newName) Defensive patterns
Strategy: validation
Validate before calling
if src == dst {
return nil // self-copy is a no-op; skip the network call
} Type guard
func isSelfCopy(src, dst string) bool { return src == dst } Try / catch
if isSelfCopy(src, dst) { return nil }
if err := adapter.CopyObject(ctx, src, dst); errors.Is(err, errSameSourceAndDest) {
return nil // treat as no-op
} Prevention
- Short-circuit when destination equals source before invoking CopyObject.
- Normalize paths (clean, consistent case) so equal paths compare equal.
- In rename UIs, disable submit when the new name is unchanged.
When it happens
Trigger: Calling CopyObject(ctx, name, name) — commonly from a rename implementation that forgot to change the destination, or user input where new name equals old name.
Common situations: Rename UIs accepting unchanged names; logic defaulting dst to src when a new name was not provided.
Related errors
- source and destination names cannot be empty
- invalid FTP configuration: host and port are required
- invalid FTP provider
- object name is empty
- invalid offset: must be >= 0
AI-assisted analysis of gofr-dev/gofr@187eb24962 (2026-09-01).
Data as JSON: /api/errors/d92b4454ec7a89ef.
Report an issue: GitHub.