jeessy2/ddns-go · error

在 zip 文件中%w:%q

Error message

在 zip 文件中%w:%q

What it means

unzip successfully opened a valid zip archive but no non-directory entry whose filename matches the executable name (matchExecutableName) was found, so it returns errExecutableNotFoundInArchive wrapped in this message along with the command name. The archive is fine; it simply doesn't contain the expected binary.

Source

Thrown at util/update/decompress.go:61

	buf, err := io.ReadAll(src)
	if err != nil {
		return nil, fmt.Errorf("%w zip 文件: %v", errCannotDecompressFile, err)
	}

	r := bytes.NewReader(buf)
	z, err := zip.NewReader(r, r.Size())
	if err != nil {
		return nil, fmt.Errorf("%w zip 文件: %s", errCannotDecompressFile, err)
	}

	for _, file := range z.File {
		_, name := filepath.Split(file.Name)
		if !file.FileInfo().IsDir() && matchExecutableName(cmd, name) {
			return file.Open()
		}
	}

	return nil, fmt.Errorf("在 zip 文件中%w:%q", errExecutableNotFoundInArchive, cmd)
}

func untar(src io.Reader, cmd string) (io.Reader, error) {
	gz, err := gzip.NewReader(src)
	if err != nil {
		return nil, fmt.Errorf("%w tar.gz 文件: %s", errCannotDecompressFile, err)
	}

	t := tar.NewReader(gz)
	for {
		h, err := t.Next()
		if errors.Is(err, io.EOF) {
			break
		}
		if err != nil {
			return nil, fmt.Errorf("%w tar.gz 文件:%s", errCannotDecompressFile, err)
		}
		_, name := filepath.Split(h.Name)

View on GitHub (pinned to 5874c2e666)

Solutions

  1. Download the zip asset matching your OS/architecture that contains the binary
  2. List the zip contents (unzip -l) and compare entry names against the expected executable name
  3. Check upstream release notes for binary renames and update the expected name/matching logic
Defensive patterns

Strategy: fallback

Validate before calling

// Optionally inspect the archive listing before extraction
zr, err := zip.OpenReader(path)
if err != nil { return err }
for _, f := range zr.File {
    if strings.HasSuffix(f.Name, executableName) { return nil }
}
return fmt.Errorf("%s not present in archive", executableName)

Try / catch

r, err := unzip(src, cmd)
if err != nil {
    if errors.Is(err, errExecutableNotFoundInArchive) {
        // wrong platform asset or renamed binary: surface actionable message
        return fmt.Errorf("update asset does not contain %q; check OS/arch of the release", cmd)
    }
    return err
}

Prevention

When it happens

Trigger: Self-update downloads a zip release that lacks a file matching the current executable's name — wrong architecture asset (e.g. arm64 zip on amd64), a source-only zip, or the project renamed its binary between releases.

Common situations: Selecting the wrong platform asset in release downloads; upstream renamed the executable in a newer release; downloading a source-code zip instead of the built release zip.

Related errors


AI-assisted analysis of jeessy2/ddns-go@5874c2e666 (2026-09-03). Data as JSON: /api/errors/8ad48c1c61f1af97. Report an issue: GitHub.