Back to publishing & release Automate semantic versioning Publish to the npm registry Harden the supply chain

Fixing Changesets Not Detecting a Version Bump

You merged a change but the Changesets release PR proposes no version bump, so the fix never ships. This page shows why Changesets sees nothing to release and how to make bumps deterministic.

Exact symptoms and error messages

Exact symptoms and error messages Exact symptoms and error messages in production JavaScript package workflows. Exact symptoms and error messages Exact symptoms and error messages in production JavaScript package workflows.
Exact symptoms and error messages — the core idea of this section at a glance.
$ pnpm changeset status
No changesets found. All packages up to date.
# but a fix was merged with no version change

Root cause analysis

Changesets derives version bumps from intent files in .changeset/, not from your commits. If no changeset file was added for the change, there is nothing to release — the tool has no signal that a package changed. This is the intent-driven half of Semantic Versioning and Release Automation; the alternative, commit-driven approach is covered in Configuring Conventional Commits and semantic-release.

Intent to release A changeset intent file drives the version and publish. add changeset .changeset/*.md version PR computed bump merge → publish release ships
Changesets releases from intent files, so no changeset means no release.

Changesets is intent-driven: it releases from the .changeset/*.md files a contributor adds, not from the commits themselves. If no changeset was added for a change, the tool correctly sees nothing to release — from its perspective, the change declared no user-facing impact. The gap is not a bug in Changesets; it is a missing intent file, which is easy to forget because the code change on its own looks complete.

This is the deliberate trade-off of the intent-driven model versus the commit-driven one. Commit-driven tools like semantic-release infer the bump from commit messages, so nothing is forgotten but the message format becomes load-bearing. Changesets asks for an explicit statement of intent, which is more work per change but produces a human-written changelog entry and a clear record of why each version moved. Neither is wrong; the failure here is simply that the intent-driven tool was used without supplying the intent.

Resolution and configuration patch

Add a changeset for every user-facing change and enforce it in CI:

Resolution and configuration patch Add a changeset for every user-facing change and enforce it in CI: Resolution and configuration patch Add a changeset for every user-facing change and enforce it in CI:
Resolution and configuration patch — the core idea of this section at a glance.
# create an intent file describing the bump
pnpm changeset
# CI: fail a PR that changes packages but adds no changeset
- run: pnpm changeset status --since=origin/main

The status check turns a missing changeset into a red build instead of a silent no-op release.

CLI validation and debug commands

CLI validation and debug commands CLI validation and debug commands in production JavaScript package workflows. CLI validation and debug commands CLI validation and debug commands in production JavaScript package workflows.
CLI validation and debug commands — the core idea of this section at a glance.
# Show what will be released
pnpm changeset status --verbose
# Confirm intent files exist for the change
ls .changeset/*.md

Prevention and CI guardrails

  • Require a changeset on any PR that modifies a publishable package.
  • Run changeset status --since=<base> in CI to block missing intents.
  • Educate contributors that commits alone do not trigger a release.
  • Use empty changesets deliberately when a change is intentionally non-releasing.
Prevention and CI guardrails Prevention and CI guardrails in production JavaScript package workflows. Prevention and CI guardrails Prevention and CI guardrails in production JavaScript package workflows.
Prevention and CI guardrails — the core idea of this section at a glance.

Enforcing a changeset in CI

The reliable fix is to make a missing changeset fail the pull request, so the intent file is never forgotten. Changesets ships a status command that can compare against a base and exit non-zero when a publishable package changed without an accompanying changeset.

Changeset CI gate A status check fails a PR missing its changeset. changeset status compare to base missing intent red build contributor adds release recorded
A required status check makes the intent-driven model self-enforcing.
- run: pnpm changeset status --since=origin/main

As a required check, this turns a silent no-op release into a red build on the PR that introduced the gap — the contributor is prompted to run pnpm changeset and describe the bump before merge. Deliberately non-releasing changes (a refactor, a docs edit) are handled by adding an empty changeset, which explicitly records 'no release needed' rather than leaving the intent ambiguous. The check makes the intent-driven model self-enforcing instead of relying on everyone remembering the extra step.

Intent-driven versus commit-driven automation

Choosing between Changesets and semantic-release is really choosing where the release intent lives. Changesets puts it in explicit intent files a contributor writes, which produces curated changelogs and handles monorepos with independently-versioned packages naturally. semantic-release infers it from conventional commit messages, which never forgets a bump but ties correctness to commit discipline and is happiest with single-package repos.

Intent vs commit Changesets against semantic-release. Model Intent lives in Best for Changesets intent files monorepos + changelogs semantic-release commit messages single-package repos
Explicit intent files versus inferred bumps from commit messages.

For a monorepo publishing several packages with human-readable changelogs, Changesets' explicit model usually wins despite the extra per-change step — and the CI status check removes the 'forgot the changeset' failure mode. For a single package where every commit already follows a convention, semantic-release's zero-extra-step automation is hard to beat. The conventional-commits setup covers the commit-driven alternative in full; the key is to pick one model and enforce it, rather than half-adopting both.

Frequently Asked Questions

Why doesn't merging a fix trigger a release?

Changesets releases from intent files, not commits. Without a .changeset/*.md file describing the bump, the tool correctly sees nothing to release. Add a changeset with the change.

How do I enforce changesets in CI?

Run changeset status --since=origin/main as a required check; it fails when a PR touches a package but adds no changeset, so missing intents are caught before merge.

Why doesn't merging a fix trigger a Changesets release?

Because Changesets releases from intent files, not commits. Without a .changeset/*.md describing the bump, the tool correctly sees nothing to release. Add a changeset with pnpm changeset, or enforce one in CI.

How do I enforce changesets so none are forgotten?

Run changeset status --since=origin/main as a required check. It fails a PR that changes a publishable package without a changeset, prompting the contributor to add one before merge.

Changesets or semantic-release — how do I choose?

Changesets uses explicit intent files, ideal for monorepos with curated changelogs; semantic-release infers bumps from conventional commits, ideal for single packages with commit discipline. Pick one model and enforce it rather than half-adopting both.

Related

Semantic Versioning and Release Automation