HMCL-dev/HMCL · error · IOException

Interrupted while waiting for pending instance writes

Error message

Interrupted while waiting for pending instance writes

What it means

Validation failure: the manifest's addons array must be present (it records loader/mod dependencies like Forge). validate() throws JsonParseException when addons is null. An empty array is acceptable; a missing one is not.

Solutions

  1. Add "addons": [] (with loader entries if needed) to the manifest JSON
  2. Re-export the pack with a compliant exporter
  3. Check that the JSON was not truncated mid-file

Example fix

// before
{"addons": null}
// after
{"addons": [{"id": "forge", "version": "14.23.5.2859"}]}
Defensive patterns

Strategy: validation

Validate before calling

if (!manifest.has("addons") || manifest.get("addons").isJsonNull())
    throw new IllegalArgumentException("Manifest missing addons array");

Try / catch

try { manifest.validate(); } catch (JsonParseException e) { /* report missing field to user */ }

Prevention

When it happens

Trigger: Importing an Mcbbs pack whose manifest JSON omits the "addons" field or sets it to null.

Common situations: Minimal hand-written manifests; tools exporting without addon metadata; manifests for vanilla packs that dropped the addons key instead of using [].

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


AI-assisted analysis of HMCL-dev/HMCL@24702dc5a0 (2026-09-10). Data as JSON: /api/errors/6338ef0b86bb6536. Report an issue: GitHub.

Appendix: source

Thrown at HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLGameRepository.java:138

        return (HMCLGameInstance) super.getInstance(id);
    }

    /// Returns the indexed instance for the given id, or `null` when it is not loaded.
    ///
    /// @param id the instance id
    /// @return the instance, or `null` when absent
    public @Nullable HMCLGameInstance findInstance(GameInstanceID id) {
        return (HMCLGameInstance) getSnapshot().findInstance(id);
    }

    /// {@inheritDoc}
    @Override
    protected void flushPendingInstanceWrites() throws IOException {
        try {
            FileSaver.waitForAllSaves();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new IOException("Interrupted while waiting for pending instance writes", e);
        }
    }

    /// Returns the persistent game directory for this repository.
    public GameDirectory getGameDirectory() {
        return gameDirectory;
    }

    /// Returns the selected instance resolved from the current repository snapshot.
    ///
    /// The property is `null` when the persisted selection is absent or is not registered in the
    /// current snapshot. Publishing a new snapshot replaces the value with that snapshot's member,
    /// even when the selected ID is unchanged.
    ///
    /// @return the read-only selected-instance property
    public ReadOnlyObjectProperty<@Nullable HMCLGameInstance> selectedInstanceProperty() {
        return selectedInstance.getReadOnlyProperty();
    }

View on GitHub (pinned to 24702dc5a0)