jeessy2/ddns-go · error

executable not found

Error message

executable not found

What it means

errExecutableNotFoundInArchive ("executable not found") is returned by unzip/untar when the archive was read successfully but no entry matches the expected command/executable name. The messages are phrased 在 zip 文件中executable not found:%q / 在 tar.gz 文件中... naming the missing command. It means the update package layout doesn't contain the expected binary.

Source

Thrown at util/update/errors.go:9

// Based on https://github.com/creativeprojects/go-selfupdate/blob/v1.1.1/errors.go

package update

import "errors"

var (
	errCannotDecompressFile        = errors.New("failed to decompress")
	errExecutableNotFoundInArchive = errors.New("executable not found")
)

View on GitHub (pinned to 5874c2e666)

Solutions

  1. Verify the downloaded asset matches your OS/arch and contains the binary (unzip -l / tar -tzf)
  2. Check the expected executable name passed to unzip/untar against the actual archive layout; update the lookup logic if names changed
  3. Use the correct latest release asset URL for your platform
  4. If the vendor changed packaging, update the updater to search nested paths or map old->new names

Example fix

// before
return nil, fmt.Errorf("在 zip 文件中%w:%q", errExecutableNotFoundInArchive, cmd)
// after
// check archive contents first:
// unzip -l update.zip | grep myapp
// or in code, match basename against cmd and search subdirectories:
if filepath.Base(f.Name) == cmd { ... }
Defensive patterns

Strategy: validation

Validate before calling

// list archive entries and confirm the executable exists before extracting
func archiveHasEntry(path, cmd string) (bool, error) {
  r, err := zip.OpenReader(path)
  if err != nil {
    return false, err
  }
  defer r.Close()
  for _, f := range r.File {
    if filepath.Base(f.Name) == cmd {
      return true, nil
    }
  }
  return false, nil
}

Type guard

func isExecutableNotFound(err error) bool {
  return errors.Is(err, update.errExecutableNotFoundInArchive)
}

Try / catch

bin, err := update.unzip(path, cmd)
if err != nil {
  if isExecutableNotFound(err) {
    return fmt.Errorf("更新包不包含可执行文件 %q,请检查下载的架构/平台是否正确", cmd)
  }
  return err
}

Prevention

When it happens

Trigger: Auto-update downloads an archive whose entries don't include the expected executable name — e.g. the release asset changed its internal directory layout, or the cmd name passed to unzip/untar doesn't match any file in the archive.

Common situations: Upstream project renamed or restructured binaries in newer releases; downloading the wrong artifact (e.g. wrong OS/arch asset); packaging script stopped putting the binary at the archive root.

Related errors


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