{"record":{"id":"b6e09c66f3994111","repo":"jeessy2/ddns-go","slug":"executable-not-found","errorCode":null,"errorMessage":"executable not found","messagePattern":"executable not found","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"util/update/errors.go","lineNumber":9,"sourceCode":"// Based on https://github.com/creativeprojects/go-selfupdate/blob/v1.1.1/errors.go\n\npackage update\n\nimport \"errors\"\n\nvar (\n\terrCannotDecompressFile        = errors.New(\"failed to decompress\")\n\terrExecutableNotFoundInArchive = errors.New(\"executable not found\")\n)\n","sourceCodeStart":1,"sourceCodeEnd":11,"githubUrl":"https://github.com/jeessy2/ddns-go/blob/5874c2e6667c69357ab95079421131104bd3fcae/util/update/errors.go#L1-L11","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Verify the downloaded asset matches your OS/arch and contains the binary (unzip -l / tar -tzf)","Check the expected executable name passed to unzip/untar against the actual archive layout; update the lookup logic if names changed","Use the correct latest release asset URL for your platform","If the vendor changed packaging, update the updater to search nested paths or map old->new names"],"exampleFix":"// before\nreturn nil, fmt.Errorf(\"在 zip 文件中%w：%q\", errExecutableNotFoundInArchive, cmd)\n// after\n// check archive contents first:\n// unzip -l update.zip | grep myapp\n// or in code, match basename against cmd and search subdirectories:\nif filepath.Base(f.Name) == cmd { ... }","handlingStrategy":"validation","validationCode":"// list archive entries and confirm the executable exists before extracting\nfunc archiveHasEntry(path, cmd string) (bool, error) {\n  r, err := zip.OpenReader(path)\n  if err != nil {\n    return false, err\n  }\n  defer r.Close()\n  for _, f := range r.File {\n    if filepath.Base(f.Name) == cmd {\n      return true, nil\n    }\n  }\n  return false, nil\n}","typeGuard":"func isExecutableNotFound(err error) bool {\n  return errors.Is(err, update.errExecutableNotFoundInArchive)\n}","tryCatchPattern":"bin, err := update.unzip(path, cmd)\nif err != nil {\n  if isExecutableNotFound(err) {\n    return fmt.Errorf(\"更新包不包含可执行文件 %q，请检查下载的架构/平台是否正确\", cmd)\n  }\n  return err\n}","preventionTips":["Download the release asset matching your OS/arch (amd64/arm64, linux/darwin/windows)","Run unzip -l / tar -tzf on the package to verify the binary is present","Keep the updater's expected executable name in sync with the upstream release layout","Pin the update manifest/URL so packaging changes upstream don't silently break matching"],"tags":["go","update","archive","missing-file"],"backgroundTag":"executable-not-found-in-archive","analyzedSha":"5874c2e6667c69357ab95079421131104bd3fcae","analyzedAt":"2026-09-03T15:41:16.799Z","contentChangedAt":"2026-09-03T15:41:16.799Z","schemaVersion":2},"datasetVersion":"2026-09-11T00:17:11.886Z"}