cli/cli · error

error extracting %q: %w

Error message

error extracting %q: %w

What it means

ExtractZip iterates archive entries, resolves each entry name against destDir via safepaths (path-traversal entries are silently skipped), then calls extractZipFile. If opening the entry, creating the destination file (O_EXCL, so pre-existing files fail), MkdirAll, or io.Copy fails, the error is wrapped with the offending entry name. Note the O_EXCL flag: extracting into a dirty destination where a file already exists produces "file already exists".

Source

Thrown at internal/zip/zip.go:36

)

// ExtractZip extracts the contents of a zip archive to destDir.
// Files that would result in path traversal are silently skipped.
// Files that would produce any other error cause the extraction to be aborted,
// and the error is returned.
func ExtractZip(zr *zip.Reader, destDir safepaths.Absolute) error {
	for _, zf := range zr.File {
		fpath, err := destDir.Join(zf.Name)
		if err != nil {
			var pathTraversalError safepaths.PathTraversalError
			if errors.As(err, &pathTraversalError) {
				continue
			}
			return err
		}

		if err := extractZipFile(zf, fpath); err != nil {
			return fmt.Errorf("error extracting %q: %w", zf.Name, err)
		}
	}
	return nil
}

func extractZipFile(zf *zip.File, dest safepaths.Absolute) (extractErr error) {
	zm := zf.Mode()
	if zm.IsDir() {
		extractErr = os.MkdirAll(dest.String(), dirMode)
		return
	}

	var f io.ReadCloser
	f, extractErr = zf.Open()
	if extractErr != nil {
		return
	}
	defer f.Close()

View on GitHub (pinned to 0eeec0b92e)

Solutions

  1. Clean the destination directory before extracting (remove partial output), since O_EXCL fails on existing files
  2. Check free disk space and write permissions on destDir
  3. Verify the archive integrity (unzip -t archive.zip) and re-download if the transfer was truncated
  4. If embedding, call ExtractZip only into a fresh empty directory you created

Example fix

// before
os.MkdirAll(dest, 0o755)
err := zip.ExtractZip(zr, dest) // re-run -> error extracting "skill/README.md": ... file exists

// after
os.RemoveAll(dest)
if err := os.MkdirAll(dest, 0o755); err != nil { return err }
err := zip.ExtractZip(zr, dest)
Defensive patterns

Strategy: validation

Validate before calling

// extract only into a fresh directory; O_EXCL makes re-extraction fail
if err := os.RemoveAll(dest); err != nil { return err }
if err := os.MkdirAll(dest, 0o755); err != nil { return err }
if err := zip.ExtractZip(zr, safepaths.MustNewAbsolute(dest)); err != nil { return err }

Try / catch

err := zip.ExtractZip(zr, dest)
if err != nil {
	var target safepaths.Absolute // best-effort cleanup so retry can succeed
	_ = os.RemoveAll(dest.String())
	return err
}

Prevention

When it happens

Trigger: Extracting a zip whose target file already exists in destDir (re-run over a partially extracted directory); disk full or permission denied during copy; unreadable/corrupt zip entry data; parent directory creation blocked.

Common situations: Retrying a failed download-extract without cleaning the destination; extracting into a directory owned by another user; truncated archive downloads producing CRC/open errors mid-entry.

Related errors


AI-assisted analysis of cli/cli@0eeec0b92e (2026-08-15). Data as JSON: /api/errors/9bc11e0110dc04a4. Report an issue: GitHub.