{"record":{"id":"7387425745b3241e","repo":"github/copilot-sdk","slug":"failed-to-extract-cli-license-w","errorCode":null,"errorMessage":"failed to extract CLI license: %w","messagePattern":"failed to extract CLI license: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/cmd/bundler/main.go","lineNumber":452,"sourceCode":"\ttempDir, err := os.MkdirTemp(\"\", \"copilot-bundler-*\")\n\tif err != nil {\n\t\treturn bundleArtifacts{}, fmt.Errorf(\"failed to create temp dir: %w\", err)\n\t}\n\tdefer os.RemoveAll(tempDir)\n\n\tbinaryPath, tarballPath, err := downloadCLIBinary(info.runtimePlatform, info.binaryName, cliVersion, tempDir)\n\tif err != nil {\n\t\treturn bundleArtifacts{}, fmt.Errorf(\"failed to download CLI binary: %w\", err)\n\t}\n\n\tif outputDir != \".\" {\n\t\tif err := os.MkdirAll(outputDir, 0755); err != nil {\n\t\t\treturn bundleArtifacts{}, fmt.Errorf(\"failed to create output directory: %w\", err)\n\t\t}\n\t}\n\tif includeLicense {\n\t\tif err := extractCLILicense(tarballPath, outputPath); err != nil {\n\t\t\treturn bundleArtifacts{}, fmt.Errorf(\"failed to extract CLI license: %w\", err)\n\t\t}\n\t}\n\n\tbinaryHash, err := sha256File(binaryPath)\n\tif err != nil {\n\t\treturn bundleArtifacts{}, fmt.Errorf(\"failed to hash output binary: %w\", err)\n\t}\n\tif err := compressZstdFile(binaryPath, outputPath); err != nil {\n\t\treturn bundleArtifacts{}, fmt.Errorf(\"failed to write output binary: %w\", err)\n\t}\n\n\trawLibPath := filepath.Join(tempDir, \"runtime.node\")\n\tif err := extractFileFromTarball(\n\t\ttarballPath,\n\t\ttempDir,\n\t\t\"package/prebuilds/\"+info.runtimePlatform+\"/runtime.node\",\n\t\t\"runtime.node\",\n\t); err != nil {","sourceCodeStart":434,"sourceCodeEnd":470,"githubUrl":"https://github.com/github/copilot-sdk/blob/cd8cf15dc3f9e762615790aaed0a771a0f392755/go/cmd/bundler/main.go#L434-L470","documentation":"When includeLicense is set, buildBundle calls extractCLILicense to pull the license file out of the downloaded CLI tarball and write it next to the output. Any failure inside that extraction (reading the tarball, locating the license entry, writing the destination) is wrapped with this message and aborts the bundle.","triggerScenarios":"extractCLILicense(tarballPath, outputPath) errors: the tarball is corrupt/truncated, the expected license file is absent from the archive, or the destination path cannot be written.","commonSituations":"A partially downloaded or checksum-invalid tarball (interrupted download, proxy interference), a CLI package version whose archive layout no longer contains the license at the expected path, or an output location that became unwritable between steps.","solutions":["Delete the cached/downloaded tarball and re-download it (verify its size/checksum) to rule out a corrupt archive.","Confirm the CLI package version still contains the license file at the path extractCLILicense expects; check archive contents with tar -tf.","Retry the bundle without --include-license if licensing output is not required for your build.","Ensure outputPath is writable and not occupied by a read-only file."],"exampleFix":"// before\nrm -rf ~/.cache/bundler/cli-*.tgz\nbundler --include-license ...\n// fails on corrupt tarball\n\n// after\nrm -rf ~/.cache/bundler/cli-*.tgz   # force clean re-download\nbundler --include-license ...","handlingStrategy":"try-catch","validationCode":"f, err := os.Open(tarballPath)\nif err != nil {\n\treturn fmt.Errorf(\"tarball unreadable: %w\", err)\n}\ndefer f.Close()\ngr, err := gzip.NewReader(f)\nif err != nil {\n\treturn fmt.Errorf(\"tarball not valid gzip (likely corrupt/truncated): %w\", err)\n}\ngr.Close()","typeGuard":"func tarballHasEntry(tarballPath, name string) bool {\n\tf, err := os.Open(tarballPath)\n\tif err != nil {\n\t\treturn false\n\t}\n\tdefer f.Close()\n\tgz, err := gzip.NewReader(f)\n\tif err != nil {\n\t\treturn false\n\t}\n\tdefer gz.Close()\n\ttr := tar.NewReader(gz)\n\tfor {\n\t\thdr, err := tr.Next()\n\t\tif err == io.EOF {\n\t\t\treturn false\n\t\t}\n\t\tif err != nil {\n\t\t\treturn false\n\t\t}\n\t\tif filepath.Clean(hdr.Name) == filepath.Clean(name) {\n\t\t\treturn true\n\t\t}\n\t}\n}","tryCatchPattern":"if err := buildBundle(...); err != nil {\n\tif strings.Contains(err.Error(), \"failed to extract CLI license\") {\n\t\tlog.Warn(\"license extraction failed; re-downloading tarball and retrying without license\")\n\t}\n\treturn err\n}","preventionTips":["Verify tarball checksums against the published release before bundling.","Pin the CLI package version so archive layout (license path) is stable.","Re-download the tarball on any extraction failure instead of reusing a cache.","Test that the output path stays writable for the duration of the build."],"tags":["tarball","extraction","license","cli"],"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-16T04:17:20.429Z"}