yeasy/docker_practice · error · Error

package.json version ${pkg.version} does not match CHANGELOG

Error message

package.json version ${pkg.version} does not match CHANGELOG ${topVersion}

What it means

This error comes from scripts/check_metadata.js, a repo CI gate run as the first step of `npm test` (package.json scripts.test). It enforces that the `version` field in package.json equals the topmost version entry in CHANGELOG.md. The script parses CHANGELOG.md with the regex /^\* ([0-9]+\.[0-9]+\.[0-9]+)\b/m, so only a line starting with `* ` followed by a semver (e.g. `* 1.9.2 2026-05-16`) is recognized; if no such line exists the captured version is undefined and the equality check fails. It exists to keep the released book version and its changelog in lockstep so builds and release notes never drift apart.

Source

Thrown at scripts/check_metadata.js:10

const fs = require('fs');

const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8'));
const changelog = fs.readFileSync('CHANGELOG.md', 'utf8');
const readme = fs.readFileSync('README.md', 'utf8');

const topVersion = changelog.match(/^\* ([0-9]+\.[0-9]+\.[0-9]+)\b/m)?.[1];

if (pkg.version !== topVersion) {
  throw new Error(`package.json version ${pkg.version} does not match CHANGELOG ${topVersion}`);
}

if (pkg.license !== 'CC-BY-NC-SA-4.0' || !readme.includes('CC BY-NC-SA 4.0')) {
  throw new Error('package.json license must match README license');
}

View on GitHub (pinned to 00d8a87f55)

Solutions

  1. Align the two values: add `* <newversion> <date>` as the topmost bullet in CHANGELOG.md (or set package.json "version" to the changelog's top version), then rerun `node scripts/check_metadata.js`.
  2. If the changelog was reformatted, restore the bullet format the regex expects: a line starting with `* ` immediately followed by MAJOR.MINOR.PATCH, e.g. `* 1.9.2 2026-05-16`.
  3. If you intentionally use a prerelease version (e.g. 1.9.3-beta.1), either drop the suffix in both files or extend the regex in scripts/check_metadata.js to accept it — but prefer plain semver to keep CI green.
  4. Automate the sync: run `npm version <newversion>` and let a commit hook or release script insert the matching CHANGELOG line in the same commit.

Example fix

// CHANGELOG.md — before
# 修订记录

## 1.9.3
* updated chapters

// CHANGELOG.md — after (regex requires a `* <semver>` line)
# 修订记录

* 1.9.3 2026-08-15
  * updated chapters

// package.json — keep in sync
{ "version": "1.9.3" }
Defensive patterns

Strategy: validation

Validate before calling

// Run before `npm test` / release to catch drift early
const fs = require('fs');
const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8'));
const top = fs.readFileSync('CHANGELOG.md', 'utf8')
  .match(/^\* ([0-9]+\.[0-9]+\.[0-9]+)\b/m)?.[1];
if (top === undefined) {
  throw new Error('CHANGELOG.md has no top-level `* <semver>` entry for the regex to match');
}
if (pkg.version !== top) {
  throw new Error(`version drift: package.json=${pkg.version} vs CHANGELOG=${top}`);
}

Try / catch

// If invoking check_metadata.js programmatically:
const { spawnSync } = require('child_process');
const r = spawnSync(process.execPath, ['scripts/check_metadata.js'], { encoding: 'utf8' });
if (r.status !== 0) {
  console.error('metadata check failed:', r.stderr.trim());
  // stop the release pipeline before building artifacts
}

Prevention

When it happens

Trigger: Running `npm test` (or `node scripts/check_metadata.js`) when (a) package.json "version" was bumped (e.g. 1.9.3) without adding a matching `* 1.9.3 ...` entry at the top of CHANGELOG.md, (b) a CHANGELOG entry was added for a version not yet set in package.json, or (c) the top CHANGELOG entry is formatted so the regex cannot match it — e.g. `## 1.9.3`, `- 1.9.3`, a leading space before `*`, or a non-semver like `1.9.3-beta.1` — which makes topVersion undefined and always mismatches.

Common situations: Release prep where the version is bumped in package.json (or by `npm version`) but the changelog update is forgotten; CHANGELOG entries rewritten in a different heading style (`##` headings instead of `* ` bullets) during a docs reformat; PRs that edit CHANGELOG.md without touching package.json; a prerelease suffix in the changelog version that the strict \d+\.\d+\.\d+ capture cannot parse, leaving topVersion stale or undefined.

Related errors


AI-assisted analysis of yeasy/docker_practice@00d8a87f55 (2026-08-15). Data as JSON: /api/errors/16d0c768e8bdd59e. Report an issue: GitHub.