LykosAI/StabilityMatrix · critical · IOException

Failed to organize files and rollback was incomplete

Error message

Failed to organize files and rollback was incomplete: {string.Join("; ", rollbackErrors)}

What it means

ApplyFileMovesAsync wraps a failed organize operation: after an exception, it attempts to roll back completed moves; if the rollback itself partially fails, it throws an IOException whose message lists the rollback errors, chaining the original exception. This indicates the models directory may be left in a mixed state.

Solutions

  1. Close applications locking the model files (UI, trainers, indexers) and retry the organize
  2. Inspect the joined rollback error list in the message and the inner exception to fix the root cause (permissions/disk space)
  3. Manually reconcile the affected files using the reported paths (move remaining files to destinations per the plan)
  4. Retry the operation after freeing disk space or fixing ACLs; take a backup of the models root before large reorganizations

Example fix

// before
try { await service.MoveModelFileAsync(model, root, dest); }
catch (IOException ex) { /* message lists rollback errors; inner ex is original cause */ }
// after
catch (IOException ex)
{
    logger.LogError(ex, "Organize failed; inner: {Inner}", ex.InnerException?.Message);
    // reconcile files listed in ex.Message, then retry
}
Defensive patterns

Strategy: try-catch

Validate before calling

foreach (var move in plan)
{
    if (!File.Exists(move.Source)) throw new FileNotFoundException(move.Source);
    if (move.Destination is { } d && File.Exists(d)) throw new IOException($"Destination exists: {d}");
}

Try / catch

try
{
    await organizationService.MoveModelFileAsync(model, root, dest);
}
catch (IOException ex) when (ex.Message.Contains("rollback was incomplete"))
{
    logger.LogError(ex, "Organize failed with partial rollback: {Msg}", ex.Message);
    // manually reconcile per ex.Message paths, then retry
}

Prevention

When it happens

Trigger: A disk error, permission denial, path-length limit, or locked file causes a move to fail mid-plan AND the compensating rollback of earlier successful moves also encounters errors (files locked, destination busy, permissions).

Common situations: Moving models while a trainer/UI holds files open; antivirus locking files mid-move; cross-volume moves failing on partial completion; permission differences between source and destination directories; disk full during a large move.

Understand the failure class

Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.

Related errors


AI-assisted analysis of LykosAI/StabilityMatrix@af93d6ef57 (2026-09-12). Data as JSON: /api/errors/444723561e48f698. Report an issue: GitHub.

Appendix: source

Thrown at StabilityMatrix.Avalonia/Services/ModelOrganizationService.cs:157

            {
                var targetDirectory = Path.GetDirectoryName(move.TargetPath);
                if (!string.IsNullOrWhiteSpace(targetDirectory))
                {
                    Directory.CreateDirectory(targetDirectory);
                }

                await FileTransfers
                    .MoveFileAsync(new FilePath(move.SourcePath), new FilePath(move.TargetPath))
                    .ConfigureAwait(false);
                completedMoves.Add(move);
            }
        }
        catch (Exception ex)
        {
            var rollbackErrors = await RollbackMovesAsync(completedMoves).ConfigureAwait(false);
            if (rollbackErrors.Count > 0)
            {
                throw new IOException(
                    $"Failed to organize files and rollback was incomplete: {string.Join("; ", rollbackErrors)}",
                    ex
                );
            }

            throw;
        }
    }

    private static void EnsureMoveTargetsAvailable(IReadOnlyList<ModelOrganizationFileMove> moves)
    {
        foreach (var move in moves.Where(move => !PathsEqual(move.SourcePath, move.TargetPath)))
        {
            if (File.Exists(move.TargetPath))
            {
                throw new FileTransferExistsException(move.SourcePath, move.TargetPath);
            }
        }

View on GitHub (pinned to af93d6ef57)