{"record":{"id":"d92b4454ec7a89ef","repo":"gofr-dev/gofr","slug":"source-and-destination-are-the-same-d92b44","errorCode":null,"errorMessage":"source and destination are the same","messagePattern":"source and destination are the same","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/gofr/datasource/file/ftp/storage_adapter.go","lineNumber":24,"sourceCode":"\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"path\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/jlaffaye/ftp\"\n\t\"gofr.dev/pkg/gofr/datasource/file\"\n)\n\nvar (\n\t// Storage adapter errors.\n\terrFTPConfigNil            = errors.New(\"FTP config is nil\")\n\terrFTPClientNotInitialized = errors.New(\"FTP client is not initialized\")\n\terrEmptyObjectName         = errors.New(\"object name is empty\")\n\terrInvalidOffset           = errors.New(\"invalid offset: must be >= 0\")\n\terrEmptySourceOrDest       = errors.New(\"source and destination names cannot be empty\")\n\terrSameSourceAndDest       = errors.New(\"source and destination are the same\")\n\terrFailedToCreateReader    = errors.New(\"failed to create reader\")\n\terrFailedToCreateWriter    = errors.New(\"failed to create writer\")\n\terrObjectNotFound          = errors.New(\"object not found\")\n\terrFailedToGetObjectAttrs  = errors.New(\"failed to get object attrs\")\n\terrFailedToDeleteObject    = errors.New(\"failed to delete object\")\n\terrFailedToListObjects     = errors.New(\"failed to list objects\")\n\terrFailedToListDirectory   = errors.New(\"failed to list directory\")\n\terrWriterAlreadyClosed     = errors.New(\"writer already closed\")\n\terrFTPConfigInvalid        = errors.New(\"invalid FTP configuration: host and port are required\")\n)\n\n// Config represents the FTP configuration.\ntype Config struct {\n\tHost        string        // FTP server hostname\n\tUser        string        // FTP username\n\tPassword    string        // FTP password\n\tPort        int           // FTP port\n\tRemoteDir   string        // Remote directory path. Base Path for all FTP Operations.","sourceCodeStart":6,"sourceCodeEnd":42,"githubUrl":"https://github.com/gofr-dev/gofr/blob/187eb24962502e91f1fee856230670958b66e89c/pkg/gofr/datasource/file/ftp/storage_adapter.go#L6-L42","documentation":"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.","triggerScenarios":"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.","commonSituations":"Rename UIs accepting unchanged names; logic defaulting dst to src when a new name was not provided.","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."],"exampleFix":"// before\nerr := adapter.CopyObject(ctx, oldName, newName) // newName == oldName\n// after\nif oldName == newName {\n    return nil // nothing to do\n}\nerr := adapter.CopyObject(ctx, oldName, newName)","handlingStrategy":"validation","validationCode":"if src == dst {\n    return nil // self-copy is a no-op; skip the network call\n}","typeGuard":"func isSelfCopy(src, dst string) bool { return src == dst }","tryCatchPattern":"if isSelfCopy(src, dst) { return nil }\nif err := adapter.CopyObject(ctx, src, dst); errors.Is(err, errSameSourceAndDest) {\n    return nil // treat as no-op\n}","preventionTips":["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."],"tags":["go","ftp","copy","validation"],"backgroundTag":"copy-source-equals-destination","analyzedSha":"187eb24962502e91f1fee856230670958b66e89c","analyzedAt":"2026-09-01T20:34:54.554Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}