Radarr/Radarr · error · IOException
Source and destination can't be the same {0}
Error message
Source and destination can't be the same {0} What it means
CloneFile refuses to operate when source.PathEquals(destination). Cloning a file onto itself would be a destructive no-op, so an IOException is thrown. PathEquals normalizes case per OS rules, so on Windows a case-only difference may also trip this.
Source
Thrown at src/NzbDrone.Common/Disk/DiskProviderBase.cs:238
public void DeleteFile(string path)
{
Ensure.That(path, () => path).IsValidPath(PathValidationType.CurrentOs);
Logger.Trace("Deleting file: {0}", path);
RemoveReadOnly(path);
File.Delete(path);
}
public void CloneFile(string source, string destination, bool overwrite = false)
{
Ensure.That(source, () => source).IsValidPath(PathValidationType.CurrentOs);
Ensure.That(destination, () => destination).IsValidPath(PathValidationType.CurrentOs);
if (source.PathEquals(destination))
{
throw new IOException(string.Format("Source and destination can't be the same {0}", source));
}
CloneFileInternal(source, destination, overwrite);
}
protected virtual void CloneFileInternal(string source, string destination, bool overwrite = false)
{
CopyFileInternal(source, destination, overwrite);
}
public void CopyFile(string source, string destination, bool overwrite = false)
{
Ensure.That(source, () => source).IsValidPath(PathValidationType.CurrentOs);
Ensure.That(destination, () => destination).IsValidPath(PathValidationType.CurrentOs);
if (source.PathEquals(destination))
{
throw new IOException(string.Format("Source and destination can't be the same {0}", source));View on GitHub (pinned to ca451608dc)
Solutions
- Normalize both paths with Path.GetFullPath and compare before calling — skip if equal
- For case-only renames on case-insensitive FS, rename via a temporary intermediate name
- Fix the caller that produced equal source and destination
- If the no-op is expected, short-circuit and return success instead of calling CloneFile
Example fix
// before
_diskProvider.CloneFile(source, destination);
// after
if (Path.GetFullPath(source) == Path.GetFullPath(destination))
{
return; // already at target
}
_diskProvider.CloneFile(source, destination); Defensive patterns
Strategy: validation
Validate before calling
if (Path.GetFullPath(source) == Path.GetFullPath(destination))
{
return; // no-op clone, skip
} Try / catch
try
{
_diskProvider.CloneFile(source, destination, overwrite);
}
catch (IOException ex) when (ex.Message.Contains("can't be the same"))
{
// source == destination; treat as success
} Prevention
- Normalize and compare paths in the caller before any clone/copy/move
- Short-circuit no-op renames instead of relying on the guard
- For case-only renames use a temp intermediate name
When it happens
Trigger: Caller computes a destination that resolves to the same path as the source; case-only rename on a case-insensitive filesystem where PathEquals already treats them as equal; bug in path-joining logic producing target == source.
Common situations: Episode already at the desired path so the clone target equals source; renaming routine that does not short-circuit the no-op case; Windows case-only rename attempts.
Related errors
- File already exists
- Directory doesn't exist. {path}
- File doesn't exist: {path}
- Unable to find file: {path}
- Source and destination can't be the same {0}
AI-assisted analysis of Radarr/Radarr@ca451608dc (2026-08-13).
Data as JSON: /api/errors/faf42ebe405249cd.
Report an issue: GitHub.