arduino/Arduino · error · IOException

Can't extract file , file already exists!

Error message

Can't extract file {outputFile}, file already exists!

What it means

When an archive entry is a regular file (or link/symlink) and a file already exists at the destination path while overwrite is false, extract() throws this IOException. It protects existing files from being silently replaced during library installation.

Solutions

  1. Call extract with overwrite=true when intentional replacement (upgrade/reinstall) is desired
  2. Remove the existing library folder from libraries/ (or the destination) before extracting
  3. Catch this IOException and prompt the user whether to overwrite, then retry with overwrite enabled

Example fix

// before
try {
  archiveExtractor.extract(archive, dest, 1); // throws if files exist
} catch (IOException e) { /* install aborts */ }
// after
archiveExtractor.extract(archive, dest, 1, true); // explicit overwrite on reinstall
Defensive patterns

Strategy: try-catch

Validate before calling

// check for existing files at archive entry paths before extracting
if (destFolder.exists()) {
  try (TarArchiveInputStream in = new TarArchiveInputStream(new FileInputStream(archiveFile))) {
    TarArchiveEntry e;
    while ((e = in.getNextTarEntry()) != null) {
      if (!e.isDirectory() && new File(destFolder, e.getName()).exists()) throw new IllegalStateException("Already installed: " + e.getName());
    }
  }
}

Try / catch

try { extractor.extract(archive, dest, 1); } catch (IOException e) { if (e.getMessage().startsWith("Can't extract file")) { boolean ok = askUserToOverwrite(); if (ok) extractor.extract(archive, dest, 1, true); } else { throw e; } }

Prevention

When it happens

Trigger: extract() into a destination folder that already contains a file with the same relative path as an archive entry, with the overwrite flag false (default).

Common situations: Reinstalling the same library version over an existing installation; Library Manager update flow racing with a manually installed copy; retrying a failed extraction that partially completed without overwrite enabled.

Understand the failure class

Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.

Related errors


AI-assisted analysis of arduino/Arduino@a0df6e0e83 (2026-09-06). Data as JSON: /api/errors/74433de653926166. Report an issue: GitHub.

Appendix: source

Thrown at arduino-core/src/cc/arduino/utils/ArchiveExtractor.java:215

          // Symbolic links are referenced with relative paths
          outputLinkedFile = new File(linkName);
          if (outputLinkedFile.isAbsolute()) {
            System.err.println(I18n.format(tr("Warning: file {0} links to an absolute path {1}"), outputFile, outputLinkedFile));
            System.err.println();
          }
        }

        // Safety check
        if (isDirectory) {
          if (outputFile.isFile() && !overwrite) {
            throw new IOException("Can't create folder " + outputFile + ", a file with the same name exists!");
          }
        } else {
          // - isLink
          // - isSymLink
          // - anything else
          if (outputFile.exists() && !overwrite) {
            throw new IOException("Can't extract file " + outputFile + ", file already exists!");
          }
        }

        // Extract the entry
        if (isDirectory) {
          if (!outputFile.exists() && !outputFile.mkdirs()) {
            throw new IOException("Could not create folder: " + outputFile);
          }
          foldersTimestamps.put(outputFile, modifiedTime);
        } else if (isLink) {
          hardLinks.put(outputFile, outputLinkedFile);
          hardLinksMode.put(outputFile, mode);
        } else if (isSymLink) {
          symLinks.put(outputFile, linkName);
          symLinksModifiedTimes.put(outputFile, modifiedTime);
        } else {
          // Create the containing folder if not exists
          if (!outputFile.getParentFile().isDirectory()) {

View on GitHub (pinned to a0df6e0e83)