fix(filesystem): make move_file fail instead of overwriting the destination (#4630)

The move_file tool description and README both state the operation fails if
the destination already exists, but the handler called fs.rename directly,
which silently overwrites the destination. Since this server ships no delete
tool, move_file effectively provided unadvertised, irreversible file
deletion: moving any file onto an existing target destroyed the target.

Add a moveFile helper in lib.ts that rejects when the destination already
exists (checked with lstat, so an existing symlink is detected rather than
followed) and only renames when the target is free, and use it from the
move_file handler. Behaviour now matches the documented contract.

Fixes #4628
This commit is contained in:
eeshsaxena 2026-08-28 22:28:51 +05:30 • committed by GitHub
commit 18ce197639
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -193,6 +193,25 @@ export async function writeFileContent(filePath: string, content: string): Promi
}
export async function moveFile(sourcePath: string, destinationPath: string): Promise<void> {
// The move_file tool contract (and README) state the operation fails if the
// destination already exists. fs.rename would silently overwrite it, which is
// a data-loss bug, so reject up front when anything - file, directory, or
// symlink - occupies the target. lstat is used so an existing symlink at the
// destination is detected rather than followed.
try {
await fs.lstat(destinationPath);
} catch (error) {
if ((error as NodeJS.ErrnoException).code === 'ENOENT') {
await fs.rename(sourcePath, destinationPath);
return;
}
throw error;
}
throw new Error(`Destination already exists: ${destinationPath}`);
}
// File Editing Functions
interface FileEdit {
oldText: string;