{"record":{"id":"2f776d3ecdcd39d8","repo":"github/copilot-sdk","slug":"license-file-not-found-in-tarball","errorCode":null,"errorMessage":"license file not found in tarball","messagePattern":"license file not found in tarball","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/cmd/bundler/main.go","lineNumber":1116,"sourceCode":"\tfor {\n\t\theader, err := tarReader.Next()\n\t\tif err == io.EOF {\n\t\t\tbreak\n\t\t}\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to read tar: %w\", err)\n\t\t}\n\t\tswitch header.Name {\n\t\tcase \"package/LICENSE.md\", \"package/LICENSE\":\n\t\t\tlicenseName := filepath.Base(licensePath)\n\t\t\tif err := extractFileFromTarballStream(tarReader, outputDir, licenseName, os.FileMode(header.Mode)); err != nil {\n\t\t\t\treturn fmt.Errorf(\"failed to write license: %w\", err)\n\t\t\t}\n\t\t\treturn nil\n\t\t}\n\t}\n\n\treturn fmt.Errorf(\"license file not found in tarball\")\n}\n\nfunc licensePathForOutput(outputPath string) string {\n\tif strings.HasSuffix(outputPath, \".zst\") {\n\t\treturn strings.TrimSuffix(outputPath, \".zst\") + \".license\"\n\t}\n\treturn outputPath + \".license\"\n}\n\nfunc licenseFileName(binaryName string) string {\n\tif strings.HasSuffix(binaryName, \".zst\") {\n\t\treturn strings.TrimSuffix(binaryName, \".zst\") + \".license\"\n\t}\n\treturn binaryName + \".license\"\n}\n\n// extractFileFromTarballStream writes the current tar entry to disk.\nfunc extractFileFromTarballStream(r io.Reader, destDir, outputName string, mode os.FileMode) error {","sourceCodeStart":1098,"sourceCodeEnd":1134,"githubUrl":"https://github.com/github/copilot-sdk/blob/cd8cf15dc3f9e762615790aaed0a771a0f392755/go/cmd/bundler/main.go#L1098-L1134","documentation":"extractCLILicense iterates all entries of the tarball and only recognizes package/LICENSE.md and package/LICENSE. If it reaches EOF without matching either name, it returns this sentinel error. It means the archive contains no license file at the expected paths.","triggerScenarios":"extractCLILicense (via buildBundle) is given a tarball whose top-level prefix is not 'package/' (e.g. 'cli-v1.2.0/LICENSE'), the license file has a different name/case (license.txt, LICENCE), or the tarball genuinely has no license entry.","commonSituations":"Upstream changed the release artifact layout after a version bump; repackaged tarball built with a different root directory name; downloading a custom or nightly build that omits the license.","solutions":["Inspect the tarball layout (tar -tzf file.tgz) and confirm the license path matches package/LICENSE.md or package/LICENSE","If the upstream layout changed, update the case labels in extractCLILicense to the new paths","Verify you are bundling the correct, official release artifact","Repackage or download a tarball that includes the license"],"exampleFix":"// before\ncase \"package/LICENSE.md\", \"package/LICENSE\":\n// after\ncase \"package/LICENSE.md\", \"package/LICENSE\", \"package/license.md\", \"package/COPYING\":","handlingStrategy":"validation","validationCode":"entries, err := listTarball(tarballPath)\nif err != nil { return err }\nhasLicense := false\nfor _, e := range entries { if e == \"package/LICENSE.md\" || e == \"package/LICENSE\" { hasLicense = true } }\nif !hasLicense { return fmt.Errorf(\"tarball %s lacks package/LICENSE(.md)\", tarballPath) }","typeGuard":null,"tryCatchPattern":"if err := extractCLILicense(tarballPath, outputDir); err != nil {\n    if strings.Contains(err.Error(), \"license file not found\") {\n        log.Printf(\"no standard license path in %s; skipping or failing loudly\", tarballPath)\n    }\n    return err\n}","preventionTips":["Inspect release artifact layout (tar -tzf) after every upstream version bump","Pin the exact artifact version/URL you bundle against","Verify artifact checksums before extraction","Keep the recognized license path list in sync with upstream packaging"],"tags":["go","tarball","license","not-found"],"backgroundTag":"file-not-found","analyzedSha":"cd8cf15dc3f9e762615790aaed0a771a0f392755","analyzedAt":"2026-09-09T18:32:31.973Z","contentChangedAt":"2026-09-09T18:32:31.973Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}