{"record":{"id":"6190f9a494822f8c","repo":"files-community/Files","slug":"couldn-t-generate-unique-name-file-skipped","errorCode":null,"errorMessage":"Couldn't generate unique name. File skipped.","messagePattern":"Couldn't generate unique name\\. File skipped\\.","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"src/Files.App.Storage/Ftp/FtpStorageFolder.cs","lineNumber":147,"sourceCode":"\t\t\tusing var ftpClient = GetFtpClient();\n\t\t\tawait ftpClient.EnsureConnectedAsync(cancellationToken);\n\n\t\t\tvar newPath = $\"{Id}/{desiredName}\";\n\t\t\tif (overwrite && await ftpClient.FileExists(newPath, cancellationToken))\n\t\t\t\tthrow new IOException(\"File already exists.\");\n\n\t\t\tusing var stream = new MemoryStream();\n\t\t\tvar result = await ftpClient.UploadStream(stream, newPath, overwrite ? FtpRemoteExists.Overwrite : FtpRemoteExists.Skip, token: cancellationToken);\n\n\t\t\tif (result == FtpStatus.Success)\n\t\t\t{\n\t\t\t\t// Success\n\t\t\t\treturn new FtpStorageFile(newPath, desiredName, this);\n\t\t\t}\n\t\t\telse if (result == FtpStatus.Skipped)\n\t\t\t{\n\t\t\t\t// Throw exception since flag CreationCollisionOption.GenerateUniqueName was not satisfied\n\t\t\t\tthrow new IOException(\"Couldn't generate unique name. File skipped.\");\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// File creation failed\n\t\t\t\tthrow new IOException(\"File creation failed.\");\n\t\t\t}\n\t\t}\n\n\t\t/// <inheritdoc/>\n\t\tpublic async Task<IChildFolder> CreateFolderAsync(string desiredName, bool overwrite = default, CancellationToken cancellationToken = default)\n\t\t{\n\t\t\tusing var ftpClient = GetFtpClient();\n\t\t\tawait ftpClient.EnsureConnectedAsync(cancellationToken);\n\n\t\t\tvar newPath = $\"{Id}/{desiredName}\";\n\t\t\tif (overwrite && await ftpClient.DirectoryExists(newPath, cancellationToken))\n\t\t\t\tthrow new IOException(\"Directory already exists.\");\n","sourceCodeStart":129,"sourceCodeEnd":165,"githubUrl":"https://github.com/files-community/Files/blob/68c68a58d4d6a5f7197e07c8fff85cfd4279c78b/src/Files.App.Storage/Ftp/FtpStorageFolder.cs#L129-L165","documentation":"Thrown by FtpStorageFolder.CreateFileAsync when UploadStream returns FtpStatus.Skipped. With overwrite=false the upload uses FtpRemoteExists.Skip, so any pre-existing file at the target path causes the server to skip the upload and FluentFTP reports Skipped. The comment indicates this path was meant to honor a GenerateUniqueName collision option that this overload does not actually implement.","triggerScenarios":"CreateFileAsync with overwrite=false (default) when {Id}/{desiredName} already exists on the FTP server; the inverted overwrite guard at line 133 does not catch it, so the skip surfaces here.","commonSituations":"Pasting a file into a folder that already contains a file of the same name with the default 'fail if exists' collision option; uploads after a partial/interrupted prior upload left a zero-byte stub.","solutions":["Pass overwrite=true if replacing the existing file is acceptable.","Generate a unique name at the call site before invoking CreateFileAsync (the overload here does not implement GenerateUniqueName despite the comment).","Pre-check with ftpClient.FileExists and either rename or delete the conflicting file first.","Fix the inverted overwrite guard (see error 1) so the existence conflict is reported at a deterministic point."],"exampleFix":"// before\nvar file = await folder.CreateFileAsync(name, overwrite: false, ct);\n\n// after\nvar attempt = 0;\nstring unique = name;\nwhile (await FtpExists(folder, unique))\n    unique = $\"{Path.GetFileNameWithoutExtension(name)} ({++attempt}){Path.GetExtension(name)}\";\nvar file = await folder.CreateFileAsync(unique, overwrite: false, ct);","handlingStrategy":"validation","validationCode":"// Ensure a unique name before creating when overwrite is false.\nstring name = desiredName;\nint i = 1;\nwhile (!overwrite && await FtpFileExists(folder, name))\n    name = $\"{Path.GetFileNameWithoutExtension(desiredName)} ({i++}){Path.GetExtension(desiredName)}\";\nawait folder.CreateFileAsync(name, overwrite, ct);","typeGuard":null,"tryCatchPattern":"try { return await folder.CreateFileAsync(name, false, ct); }\ncatch (IOException ex) when (ex.Message.Contains(\"skipped\", StringComparison.OrdinalIgnoreCase))\n{ /* generate a unique name and retry */ }","preventionTips":["This overload does not implement GenerateUniqueName despite the comment; compute unique names yourself.","Pre-check existence to avoid relying on the Skipped result.","Pass overwrite=true when replacement is acceptable."],"tags":["ftp","storage","file-creation","collision"],"backgroundTag":null,"analyzedSha":"68c68a58d4d6a5f7197e07c8fff85cfd4279c78b","analyzedAt":"2026-08-13T10:34:54.614Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}