Grasscutters/Grasscutter · error · RuntimeException

Failed to write to file.

Error message

Failed to write to file.

What it means

Wraps any IOException thrown while writing the command dump to commands.json via Files.writeString, replacing the original exception with a generic RuntimeException. It indicates the file exists but its content could not be written.

Source

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

                                    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();
        Language.loadTextMaps();

        // Convert all known avatars to an avatar map.
        var dump = new HashMap<Integer, AvatarInfo>();
        GameData.getAvatarDataMap()
                .forEach(
                        (id, avatar) -> {

View on GitHub (pinned to f373827a83)

Solutions

  1. Free disk space / raise quota and re-run the dump.
  2. Close programs locking commands.json, then re-run.
  3. Ensure the user has write permission on commands.json after creation.
  4. If it persists, patch the catch block to log the underlying IOException cause for diagnosis.

Example fix

// before
catch (IOException ignored) { throw new RuntimeException("Failed to write to file."); }
// after
catch (IOException e) { throw new RuntimeException("Failed to write to file.", e); }
Defensive patterns

Strategy: try-catch

Validate before calling

File f = new File("commands.json");
if (f.exists() && (!f.canWrite() || f.getFreeSpace() == 0))
    throw new IllegalStateException("Cannot write commands.json: permissions or disk space");

Type guard

static boolean isWritableOutput(String name) {
    File f = new File(name);
    try { return !f.exists() || f.canWrite(); } catch (SecurityException e) { return false; }
}

Try / catch

try {
    dumpCommands();
} catch (RuntimeException e) {
    if ("Failed to write to file.".equals(e.getMessage())) {
        LOGGER.warn("Write failed — check disk space/locks on commands.json", e);
    } else throw e;
}

Prevention

When it happens

Trigger: Files.writeString(file.toPath(), JsonUtils.encode(dump)) throwing IOException — e.g. disk full, file locked by another process, permission revoked, or the file deleted between creation and write.

Common situations: Disk quota exceeded mid-write; commands.json opened with an exclusive lock (Windows); running on a full tmpfs; JsonUtils.encode output larger than available space.

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 Grasscutters/Grasscutter@f373827a83 (2026-09-03). Data as JSON: /api/errors/38d2cd18e6f3de7f. Report an issue: GitHub.