ThreeMammals/Ocelot · error · Exception
CreateGitHubRelease: StatusCode =
Error message
CreateGitHubRelease: StatusCode =
What it means
CreateGitHubRelease POSTs to https://api.github.com/repos/ThreeMammals/Ocelot/releases and requires HTTP 201 Created. Any other status (401, 422, 403, etc.) throws this error. The detailed status is logged to build output before throwing.
Solutions
- Read the logged 'CreateGitHubRelease: StatusCode = ...' value and the API response body for the precise cause.
- 401/403: regenerate the GitHub token with correct 'repo' scope and update the CI secret.
- 422 duplicate tag: delete the existing release/tag or skip release creation if it already exists.
- 429/403 rate limit: retry after the rate-limit window or use a token with higher quota.
- Check https://www.githubstatus.com if 5xx statuses appear.
Example fix
// before
var msg = "CreateGitHubRelease: StatusCode = " + result.StatusCode;
// after
var body = await result.Content.ReadAsStringAsync();
var msg = $"CreateGitHubRelease: StatusCode = {result.StatusCode}, Body = {body}"; Defensive patterns
Strategy: retry
Validate before calling
// pre-check before creating the release
var existing = client.GetAsync("https://api.github.com/repos/ThreeMammals/Ocelot/releases/tags/" + tagName).Result;
if (existing.StatusCode == HttpStatusCode.OK) throw new Exception($"Release for tag {tagName} already exists"); Try / catch
try { var release = CreateGitHubRelease(...); }
catch (Exception ex) when (ex.Message.Contains("StatusCode = ")) { Error($"GitHub release creation failed: {ex.Message}"); throw; } Prevention
- Use a token with 'repo' scope stored in CI secrets
- Check for an existing release/tag before creating (idempotency)
- Log the response body, not just StatusCode
- Watch GitHub API rate limits during busy CI periods
When it happens
Trigger: GitHub API returns non-201: invalid/expired GITHUB_TOKEN (401), missing repo scope on the token (403), validation failure like duplicate tag name or bad release body (422), or rate limiting (403/429).
Common situations: Token without 'repo' scope; tag_name already exists because the release task ran twice; rate-limited during busy CI hours; wrong API payload after Cake/addin upgrade.
Related errors
- CompleteGitHubRelease: StatusCode =
- UploadFileToGitHubRelease: StatusCode is
- Stable release should happen via CI/CD
AI-assisted analysis of ThreeMammals/Ocelot@d1f22d9304 (2026-09-12).
Data as JSON: /api/errors/4bb6ce5585459e79.
Report an issue: GitHub.
Appendix: source
Thrown at build.cake:1013
client.DefaultRequestHeaders.Add("Accept", "application/vnd.github+json");
client.DefaultRequestHeaders.Add("X-GitHub-Api-Version", "2022-11-28");
}
private dynamic CreateGitHubRelease()
{
var body = ReleaseNotesAsJson();
var json = $"{{ \"tag_name\": \"{versioning.NuGetVersion}\", \"target_commitish\": \"{versioning.BranchName}\", \"name\": \"{versioning.NuGetVersion}\", \"body\": \"{body}\", \"draft\": true, \"prerelease\": true, \"generate_release_notes\": false }}";
var content = new System.Net.Http.StringContent(json, System.Text.Encoding.UTF8, "application/json");
using (var client = new System.Net.Http.HttpClient())
{
SetupGitHubClient(client);
var result = client.PostAsync("https://api.github.com/repos/ThreeMammals/Ocelot/releases", content).Result;
if (result.StatusCode != System.Net.HttpStatusCode.Created)
{
var msg = "CreateGitHubRelease: StatusCode = " + result.StatusCode;
Information(msg);
throw new Exception(msg);
}
var releaseData = result.Content.ReadAsStringAsync().Result;
dynamic releaseJSON = Newtonsoft.Json.JsonConvert.DeserializeObject<Newtonsoft.Json.Linq.JObject>(releaseData);
Information("CreateGitHubRelease: Release ID is " + releaseJSON.id);
return releaseJSON;
}
}
private string ReleaseNotesAsJson()
{
var body = _File_.ReadAllText(releaseNotesFile, System.Text.Encoding.UTF8);
return System.Text.Encodings.Web.JavaScriptEncoder.Default.Encode(body);
}
private void UploadFileToGitHubRelease(dynamic release, FilePath file)
{
var data = _File_.ReadAllBytes(file.FullPath);
var content = new System.Net.Http.ByteArrayContent(data);
View on GitHub (pinned to d1f22d9304)