{"record":{"id":"884f6a8baa035948","repo":"github/copilot-sdk","slug":"failed-to-fetch-legacy-package-lock-json-s","errorCode":null,"errorMessage":"failed to fetch legacy package-lock.json: %s","messagePattern":"failed to fetch legacy package-lock\\.json: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/cmd/bundler/main.go","lineNumber":358,"sourceCode":"\n\tif packageJSON.CopilotCLIVersion == \"\" {\n\t\treturn fetchLegacyCLIVersionFromRepo(gitRef)\n\t}\n\n\treturn packageJSON.CopilotCLIVersion, nil\n}\n\nfunc fetchLegacyCLIVersionFromRepo(gitRef string) (string, error) {\n\turl := fmt.Sprintf(packageLockURLFmt, gitRef)\n\tfmt.Printf(\"Falling back to %s...\\n\", url)\n\n\tresp, err := http.Get(url)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to fetch legacy package-lock.json: %w\", err)\n\t}\n\tdefer resp.Body.Close()\n\tif resp.StatusCode != http.StatusOK {\n\t\treturn \"\", fmt.Errorf(\"failed to fetch legacy package-lock.json: %s\", resp.Status)\n\t}\n\n\tvar packageLock struct {\n\t\tPackages map[string]struct {\n\t\t\tVersion string `json:\"version\"`\n\t\t} `json:\"packages\"`\n\t}\n\tif err := json.NewDecoder(resp.Body).Decode(&packageLock); err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to parse legacy package-lock.json: %w\", err)\n\t}\n\tpkg, ok := packageLock.Packages[\"node_modules/@github/copilot\"]\n\tif !ok || pkg.Version == \"\" {\n\t\treturn \"\", fmt.Errorf(\"could not find copilotCliVersion in package.json or @github/copilot in package-lock.json\")\n\t}\n\treturn pkg.Version, nil\n}\n\n// isHex returns true if s contains only hexadecimal characters.","sourceCodeStart":340,"sourceCodeEnd":376,"githubUrl":"https://github.com/github/copilot-sdk/blob/cd8cf15dc3f9e762615790aaed0a771a0f392755/go/cmd/bundler/main.go#L340-L376","documentation":"This error is returned when the HTTP response for the legacy package-lock.json has a non-200 status code. The bundler includes resp.Status (e.g. '404 Not Found') so the developer can see exactly what the server said. It typically means the gitRef is invalid or the file no longer exists at that ref.","triggerScenarios":"http.Get succeeds but resp.StatusCode != http.StatusOK — most commonly 404 when the gitRef does not exist or package-lock.json was removed/renamed at that ref; also 403 rate limiting or 5xx server errors in fetchLegacyCLIVersionFromRepo.","commonSituations":"Typo or stale tag/branch in gitRef; repo restructured so package-lock.json moved; GitHub API rate limiting returning 403; transient GitHub 5xx outages during CI.","solutions":["Check the HTTP status in the error message; a 404 means verify the gitRef and file path.","Confirm package-lock.json still exists at the given ref in the repository.","If 403, wait out or raise the GitHub rate limit (authenticated requests).","Retry on 5xx; transient server errors resolve themselves.","Fix the primary version source so the legacy fallback path is not needed."],"exampleFix":"// before\nif resp.StatusCode != http.StatusOK {\n\treturn \"\", fmt.Errorf(\"failed to fetch legacy package-lock.json: %s\", resp.Status)\n}\n// after\nif resp.StatusCode == http.StatusNotFound {\n\treturn \"\", fmt.Errorf(\"legacy package-lock.json not found at ref %q (check gitRef): %s\", gitRef, resp.Status)\n}\nif resp.StatusCode != http.StatusOK {\n\treturn \"\", fmt.Errorf(\"failed to fetch legacy package-lock.json: %s\", resp.Status)\n}","handlingStrategy":"fallback","validationCode":"resp, err := http.Head(u)\nif err != nil || resp.StatusCode != http.StatusOK {\n\treturn fmt.Errorf(\"lockfile URL %s not reachable: %v\", u, err)\n}","typeGuard":null,"tryCatchPattern":"v, err := fetchLegacyCLIVersionFromRepo(ref)\nif err != nil {\n\tvar httpErr *HTTPStatusError\n\tif errors.As(err, &httpErr) && httpErr.Code == http.StatusNotFound {\n\t\t// try a different gitRef\n\t}\n}","preventionTips":["Verify the gitRef exists (git ls-remote) before building the URL.","Check that package-lock.json exists at that ref before running.","Handle 403 rate limiting with authenticated requests or backoff.","Monitor GitHub status during CI runs to distinguish outages from real 404s."],"tags":["http","http-404","fallback","github"],"backgroundTag":"http-error-response","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"}