HMCL-dev/HMCL · error · IOException
Unrecognized asset object
Error message
Unrecognized asset object ${name} in asset ${assetId} of version ${id} What it means
DefaultGameInstance.getAssetObject(name, assetId, id) resolves an asset object name from the asset index to a concrete file path. Any unexpected exception (beyond plain IOException) while looking up or reconstructing the asset object is wrapped in an IOException 'Unrecognized asset object <name> in asset <assetId> of version <id>'. It signals the asset index lacks an entry for the requested object or its stored metadata cannot be interpreted.
Solutions
- Confirm the asset object name exists in assets/indexes/<assetId>.json; if not, use the correct assetId for the Minecraft version being launched
- Re-download the full asset index for that version so all entries are present
- Catch the IOException, log name/assetId/id, and re-run asset verification (download missing assets) before retrying
- Avoid mixing version ids and assetIds from different Minecraft versions when calling getAssetObject
Example fix
// before Optional<Path> obj = instance.getAssetObject(name, "legacy", "1.7.10"); // after // use the assetId actually declared by the version json String assetId = versionJson.getAssets(); Optional<Path> obj = instance.getAssetObject(name, assetId, "1.7.10");
Defensive patterns
Strategy: try-catch
Validate before calling
AssetIndex idx = instance.getAssetIndex(assetId); boolean known = idx.getObject(name) != null; // verify entry exists before resolving path
Try / catch
try {
Optional<Path> obj = instance.getAssetObject(name, assetId, versionId);
} catch (IOException e) {
LOG.warning("Unresolved asset " + name + " for " + assetId + ", running asset verification");
verifyAndDownloadAssets(assetId);
} Prevention
- Use the assetId declared by the version JSON, never a hardcoded one
- Re-download the asset index rather than editing it
- Log name/assetId/version on failure to speed diagnosis
When it happens
Trigger: Requesting an asset object whose hash/entry is absent from the parsed AssetIndex; AssetIndex throwing during virtual/legacy layout reconstruction; malformed asset index entries encountered while resolving the name.
Common situations: Mod or launcher code referencing a resource key not present in the version's asset index; mixing asset indexes between Minecraft versions (old version id with a newer assetId); partially repaired/corrupt asset index json missing entries.
Understand the failure class
Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.
Related errors
- Asset index file malformed
- Theme-pack asset source is not a regular file:
- Theme pack directory does not contain
- Theme pack does not contain
- Invalid theme-pack manifest
AI-assisted analysis of HMCL-dev/HMCL@24702dc5a0 (2026-09-10).
Data as JSON: /api/errors/1d2ddb82f209479a.
Report an issue: GitHub.
Appendix: source
Thrown at HMCLCore/src/main/java/org/jackhuang/hmcl/game/DefaultGameInstance.java:328
return reconstructAssets(assetId);
} catch (IOException | JsonParseException e) {
LOG.error("Unable to reconstruct asset directory", e);
return getLayout().getAssetDirectory();
}
}
/// {@inheritDoc}
@Override
public Optional<Path> getAssetObject(String assetId, String name) throws IOException {
try {
@Nullable AssetObject assetObject = getAssetIndex(assetId).getObjects().get(name);
return assetObject != null
? Optional.of(getLayout().getAssetObject(assetObject))
: Optional.empty();
} catch (IOException e) {
throw e;
} catch (Exception e) {
throw new IOException(
"Unrecognized asset object " + name + " in asset " + assetId + " of version " + id,
e);
}
}
/// Reconstructs virtual and legacy resource layouts for an asset index when required.
///
/// @param assetId the asset index ID
/// @return the directory to supply at launch time
/// @throws IOException if an asset cannot be copied
/// @throws JsonParseException if the asset index is malformed
private Path reconstructAssets(String assetId) throws IOException, JsonParseException {
Path assetsDir = getLayout().getAssetDirectory();
Path indexFile = getLayout().getAssetIndexFile(assetId);
Path virtualRoot = assetsDir.resolve("virtual").resolve(assetId);
if (!Files.isRegularFile(indexFile)) {
return assetsDir;View on GitHub (pinned to 24702dc5a0)