{"record":{"id":"3c930ca4ea1ea036","repo":"wtfutil/wtf","slug":"s-3c930c","errorCode":null,"errorMessage":"%s","messagePattern":"%s","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"modules/travisci/client.go","lineNumber":74,"sourceCode":"\tif err != nil {\n\t\treturn nil, err\n\t}\n\treq.Header.Add(\"Accept\", \"application/json\")\n\treq.Header.Add(\"Content-Type\", \"application/json\")\n\treq.Header.Add(\"Travis-API-Version\", \"3\")\n\n\tbearer := fmt.Sprintf(\"token %s\", settings.apiKey)\n\treq.Header.Add(\"Authorization\", bearer)\n\n\thttpClient := &http.Client{}\n\tresp, err := httpClient.Do(req)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer func() { _ = resp.Body.Close() }()\n\n\tif resp.StatusCode < 200 || resp.StatusCode > 299 {\n\t\treturn nil, fmt.Errorf(\"%s\", resp.Status)\n\t}\n\n\treturn resp, nil\n}\n","sourceCodeStart":56,"sourceCodeEnd":79,"githubUrl":"https://github.com/wtfutil/wtf/blob/bb838c1ccb0f0f3223690df44afdec663d622881/modules/travisci/client.go#L56-L79","documentation":"travisBuildRequest wraps Travis CI API calls and enforces a 2xx status; anything outside 200-299 is rejected with the raw resp.Status string. Callers (BuildsFor) then fail with that status text, e.g. \"404 Not Found\" or \"403 Forbidden\".","triggerScenarios":"Any Travis API endpoint returning 300+: 403 when the token is missing/expired/insufficient, 404 for wrong repo slug or wrong API host (org vs com), 429 rate limiting, 5xx Travis outages.","commonSituations":"Travis CI .org vs .com migration (repo lives on the other host); expired TRAVIS_TOKEN; repository renamed or transferred so the slug is stale; open-source repos moved off travis-ci.org after its shutdown.","solutions":["Check the status string: 404 usually means org-vs-com host mismatch — verify the configured API URL","Regenerate the Travis CI API token if you get 403","Confirm the repository slug matches the current GitHub repo name","Retry later for 429/5xx; Travis may be degraded"],"exampleFix":"// before\napiURL: \"https://api.travis-ci.org/repo/my-org/my-repo/builds\" // repo moved to .com\n// after\napiURL: \"https://api.travis-ci.com/repo/my-org/my-repo/builds\"","handlingStrategy":"retry","validationCode":"if repoSlug == \"\" || strings.Count(repoSlug, \"%2F\") == 0 && !strings.Contains(repoSlug, \"/\") { return errors.New(\"repo slug must be owner%2Fname\") }","typeGuard":"func isAuthError(status string) bool { return strings.HasPrefix(status, \"403\") || strings.HasPrefix(status, \"401\") }","tryCatchPattern":"builds, err := t.BuildsFor()\nif err != nil {\n    if strings.HasPrefix(err.Error(), \"404\") { switchAPIHost(orgToCom) }\n    else if strings.HasPrefix(err.Error(), \"403\") { refreshToken() }\n    else { log.Printf(\"travis: %v\", err) }\n}","preventionTips":["Confirm the repo lives on travis-ci.com (org is shut down for most repos)","Regenerate the API token periodically and store it in env, not config files","Keep the repo slug in sync with GitHub renames","Use exponential backoff for 429/5xx responses"],"tags":["http","travis-ci","network","go"],"backgroundTag":"http-non-200-response","analyzedSha":"bb838c1ccb0f0f3223690df44afdec663d622881","analyzedAt":"2026-09-03T17:02:45.030Z","contentChangedAt":"2026-09-03T17:02:45.030Z","schemaVersion":2},"datasetVersion":"2026-09-11T00:17:11.886Z"}