arduino/Arduino · error · IOException
Invalid archive: it must contain a single root folder
Error message
Invalid archive: it must contain a single root folder
What it means
When extract() is asked to strip a root folder (stripPath > 0), it computes the common path prefix from the first entry's name by skipping stripPath '/' characters. If the entry name contains fewer slashes than requested, it throws this IOException, because the archive does not have the single root folder the caller expects to strip.
Solutions
- Repackage the archive so all files sit under a single top-level folder named after the library (e.g. MyLibrary/src/...)
- Call extract with stripPath=0 if the archive legitimately has no root folder and you want files extracted as-is
- Inspect the archive (tar -tf) to confirm the directory layout before extracting
Example fix
// before archiveExtractor.extract(archiveFile, destFolder, 1); // archive is flat // after (repack with root folder) OR: archiveExtractor.extract(archiveFile, destFolder, 0); // no strip requested
Defensive patterns
Strategy: validation
Validate before calling
// inspect first entry layout before choosing stripPath
try (TarArchiveInputStream in = new TarArchiveInputStream(new FileInputStream(archiveFile))) {
TarArchiveEntry e = in.getNextTarEntry();
if (e != null && e.getName().indexOf('/') == -1) throw new IllegalArgumentException("Archive has no root folder; use stripPath=0 or repackage");
} Try / catch
try { extractor.extract(archive, dest, 1); } catch (IOException e) { if (e.getMessage().contains("single root folder")) { extractor.extract(archive, dest, 0); } else { throw e; } } Prevention
- Package libraries under a single top-level folder named after the library
- Verify with `tar -tf lib.tar.gz | head -1` that entries start with 'LibName/'
- Avoid flat archives when the installer strips a path prefix
When it happens
Trigger: extract(file, dest, stripPath=N) with N=1 (typical) but the first archive entry's path has no '/' — e.g. the archive contains files at its root or a single file instead of a top-level directory.
Common situations: Library released as a flat archive (files at archive root, no wrapping folder); archive whose first entry is './name' or a bare filename; someone re-zips library contents without the standard 'LibraryName/' root directory.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Archive format not supported.
- Invalid archive: it must contain a single root folder while…
- Error opening serial port
- 'Unable to list files of library in ' + libFolder
- 'arch' folder is no longer supported! See…
AI-assisted analysis of arduino/Arduino@a0df6e0e83 (2026-09-06).
Data as JSON: /api/errors/c14fe6c936ef20e0.
Report an issue: GitHub.
Appendix: source
Thrown at arduino-core/src/cc/arduino/utils/ArchiveExtractor.java:170
continue;
}
if (entry instanceof TarArchiveEntry) {
TarArchiveEntry tarEntry = (TarArchiveEntry) entry;
mode = tarEntry.getMode();
isLink = tarEntry.isLink();
isSymLink = tarEntry.isSymbolicLink();
linkName = tarEntry.getLinkName();
}
// On the first archive entry, if requested, detect the common path
// prefix to be stripped from filenames
if (stripPath > 0 && pathPrefix.isEmpty()) {
int slash = 0;
while (stripPath > 0) {
slash = name.indexOf("/", slash);
if (slash == -1) {
throw new IOException("Invalid archive: it must contain a single root folder");
}
slash++;
stripPath--;
}
pathPrefix = name.substring(0, slash);
}
// Strip the common path prefix when requested
if (!name.startsWith(pathPrefix)) {
throw new IOException("Invalid archive: it must contain a single root folder while file " + name + " is outside " + pathPrefix);
}
name = name.substring(pathPrefix.length());
if (name.isEmpty()) {
continue;
}
File outputFile = new File(destFolder, name);
File outputLinkedFile = null;View on GitHub (pinned to a0df6e0e83)