RSS

GitHub changed their API without warning and broke our production system

GitHub API Tooling Automation
In 2022, I wrote about GitHub Actions API limitations, specifically that workflow_dispatch didn't return a run ID. GitHub finally fixed it this week. Then broke Terrateam and likely other systems that haven't noticed yet.

There is a special class of failure that only shows up once people actually depend on you.

Not a bug. Not an outage. Not a missing feature.

A contract violation.

A few hours ago, GitHub shipped a change to the GitHub Actions API that quietly broke that contract.

What changed

The endpoint POST /repos/{owner}/{repo}/actions/workflows/{workflow_id}/dispatches used to return 204 No Content.

This was not folklore. It was documented. It was in GitHub's OpenAPI schema. SDKs relied on it. Orchestration systems like Terrateam relied on it.

Now it returns 200 OK with a JSON body containing a workflow run ID.

And GitHub's own OpenAPI schema still says 204:

"responses": {
  "204": {
    "description": "Response"
  }
}

The official documentation has not been updated either.

Returning the run ID is a good feature. People have been asking for it since 2022. I asked for it in that blog post. GitHub said in a blog post this change was coming in 2026.

But instead of a preview header, a versioned endpoint, a migration window, or even a changelog entry, they flipped the behavior in production.

Why this broke things

Changing HTTP status codes is a breaking change.

Status codes are not decoration. They are control flow. They tell clients whether to parse a body, whether to retry, whether a request succeeded, and which code path to execute next.

If a client expects 204 No Content and you return 200 OK with a body, you have broken the contract. Even if the new behavior is better. Even if it adds useful information.

Our code validated the status code. Anyone following GitHub's own OpenAPI schema validated the status code.

We all broke.

The real problem

The issue is not that GitHub finally returned a workflow run ID. That is a good feature.

The issue is that they shipped a breaking change without telling anyone.

No deprecation notice. No changelog entry. No preview header. No opt-in. No heads-up to integrators.

For a platform at the center of the software supply chain, this is not a small thing.

CI and automation tooling lives and dies on predictability. When APIs silently change behavior, you are left with two options:

We have been building on GitHub Actions since 2021. We have worked around plenty of limitations. We understand that APIs evolve. But this is different. This is changing documented behavior without warning.

What should have happened

This could have been done correctly:

Any of these would have worked. All of them are standard practice for breaking changes.

Instead, they changed it in production and did not update the schema or documentation.

What we are doing about it

We fixed Terrateam to handle both 200 and 204 responses.

But that is not the point.

The point is that we should not have to defensively code against GitHub's own documented API contract. The point is that their OpenAPI schema should match reality. The point is that breaking changes should be announced.

APIs are promises

HTTP status codes are not suggestions. They are part of the contract.

When you change them without warning, you are telling integrators that the documentation is optional and the contract is provisional.

GitHub, this feature is welcome. The way it shipped is not.

Communicate breaking changes. Update your schema. Give integrators a heads-up. Do not quietly change contracts and call it progress.

People are building real systems on top of this.