Grasscutters/Grasscutter · error · RuntimeException

Failed to delete file.

Error message

Failed to delete file.

What it means

Thrown by Dumpers.dumpCommands when an existing commands.json cannot be deleted before the dump is recreated. Java's File.delete() returns false (rather than throwing) when deletion fails, so the dumper converts that into an explicit RuntimeException.

Source

Thrown at src/main/java/emu/grasscutter/tools/Dumpers.java:99

                                            this.addAll(List.of(command.aliases()));
                                        }
                                    };

                            // Add the command info to the list.
                            dump.put(
                                    command.label(),
                                    new CommandInfo(
                                            labels,
                                            description,
                                            List.of(command.usage()),
                                            List.of(command.permission(), command.permissionTargeted()),
                                            command.targetRequirement()));
                        });

        try {
            // Create a file for the dump.
            var file = new File("commands.json");
            if (file.exists() && !file.delete()) throw new RuntimeException("Failed to delete file.");
            if (!file.exists() && !file.createNewFile())
                throw new RuntimeException("Failed to create file.");

            // Write the dump to the file.
            Files.writeString(file.toPath(), JsonUtils.encode(dump));
        } catch (IOException ignored) {
            throw new RuntimeException("Failed to write to file.");
        }
    }

    /**
     * Dumps all avatars to a CSV file.
     *
     * @param locale The language to dump the avatars in.
     */
    static void dumpAvatars(String locale) {
        // Reload resources.
        ResourceLoader.loadAll();

View on GitHub (pinned to f373827a83)

Solutions

  1. Close any program holding commands.json open (editors, viewers, antivirus scans) and re-run the dump.
  2. Check that the working directory is writable (permissions / not a read-only mount).
  3. Delete commands.json manually if it is stale, then re-run.
  4. Run the tool from a directory where the user has write access.

Example fix

// before
// $ javac ... && java emu.grasscutter.tools.Dumpers  -> RuntimeException: Failed to delete file.
// after
// $ rm -f commands.json && java emu.grasscutter.tools.Dumpers
Defensive patterns

Strategy: validation

Validate before calling

File file = new File("commands.json");
if (file.exists() && !file.canWrite()) {
    System.err.println("commands.json is locked or read-only; close it and retry.");
    return;
}

Type guard

static boolean canRegenerate(String name) {
    File f = new File(name);
    return !f.exists() || (f.isFile() && f.canWrite() && f.delete());
}

Try / catch

try {
    dumpCommands();
} catch (RuntimeException e) {
    if ("Failed to delete file.".equals(e.getMessage())) {
        LOGGER.warn("Close any program using commands.json and retry.");
    } else throw e;
}

Prevention

When it happens

Trigger: Calling dumpCommands while commands.json exists in the working directory and file.delete() returns false — typically the file is locked/open by another process, is read-only, or the process lacks write permission on the directory.

Common situations: Having commands.json open in an editor/viewer while running the dump tool; read-only working directory or insufficient permissions; on Windows, antivirus or another process holding a handle to the file.

Related errors


AI-assisted analysis of Grasscutters/Grasscutter@f373827a83 (2026-09-03). Data as JSON: /api/errors/6657686d6c73d947. Report an issue: GitHub.