{"record":{"id":"9e4fecea70676f64","repo":"jeessy2/ddns-go","slug":"tar-gz-w-q","errorCode":null,"errorMessage":"在 tar.gz 文件中%w：%q","messagePattern":"在 tar\\.gz 文件中%w：%q","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"util/update/decompress.go","lineNumber":84,"sourceCode":"\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"%w tar.gz 文件: %s\", errCannotDecompressFile, err)\n\t}\n\n\tt := tar.NewReader(gz)\n\tfor {\n\t\th, err := t.Next()\n\t\tif errors.Is(err, io.EOF) {\n\t\t\tbreak\n\t\t}\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"%w tar.gz 文件：%s\", errCannotDecompressFile, err)\n\t\t}\n\t\t_, name := filepath.Split(h.Name)\n\t\tif matchExecutableName(cmd, name) {\n\t\t\treturn t, nil\n\t\t}\n\t}\n\treturn nil, fmt.Errorf(\"在 tar.gz 文件中%w：%q\", errExecutableNotFoundInArchive, cmd)\n}\n\nfunc matchExecutableName(cmd, target string) bool {\n\treturn cmd == target || cmd+\".exe\" == target\n}\n","sourceCodeStart":66,"sourceCodeEnd":90,"githubUrl":"https://github.com/jeessy2/ddns-go/blob/5874c2e6667c69357ab95079421131104bd3fcae/util/update/decompress.go#L66-L90","documentation":"untar in util/update/decompress.go iterates a tar.gz archive looking for an entry whose base name matches the requested executable (matchExecutableName accepts exact match or cmd+\".exe\"). If no entry matches before the archive is exhausted, it returns this wrapped error combining errExecutableNotFoundInArchive with the requested command name. It signals that the downloaded archive does not contain the binary the updater expected.","triggerScenarios":"Calling untar (directly or via the update flow's downloadAssetFromURL/to path) with a cmd whose base name does not equal any tar entry's filepath.Split(h.Name) base name, nor cmd+\".exe\". E.g. archive ships bin/tool.gz, nested paths whose split base differs, or asking for the wrong command name.","commonSituations":"Upstream release renamed or repackaged the binary; updater config points at an old asset; Windows-vs-Linux naming mismatch (.exe only checked one way); archive layout changed so the binary sits under a directory with a different split base name.","solutions":["Verify the exact base name of the executable inside the tar.gz (tar -tzf file.tar.gz) and request that exact cmd.","If the upstream binary was renamed, update the cmd passed to untar or the update configuration to the new name.","Confirm you downloaded the archive for the correct OS/arch; a linux asset will not contain tool.exe or a matching name for a windows cmd.","Check errExecutableNotFoundInArchive with errors.Is to distinguish this case from decompression failures and surface a clear message to users."],"exampleFix":"// before\nexe, err := untar(rc, \"mytool\")\n// after (match actual archive entry)\nexe, err := untar(rc, \"mytool-bin\") // archive contains mytool-bin / mytool-bin.exe","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"exe, err := untar(rc, cmd)\nif err != nil {\n\tif errors.Is(err, errExecutableNotFoundInArchive) {\n\t\treturn fmt.Errorf(\"binary %q missing from downloaded archive; verify release asset\", cmd)\n\t}\n\treturn err\n}","preventionTips":["Inspect archive contents (tar -tzf) after download and assert the expected binary exists before extraction.","Pin/verify release assets by checksum so renamed binaries are caught early.","Request the OS-appropriate name (include .exe expectation on Windows).","Use errors.Is against errExecutableNotFoundInArchive for precise handling."],"tags":["go","archive","tar","updater"],"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"}