cover.jpg

changesets warn received 404 for npm info on pre-release

3 min read

I work on monorepo setting up changesets to a project and found a problem when working with pre-release versions.

What is changesets

changesets is a versioning and changelogs for monorepo. By writing impacts and change descriptions in markdown changesets file with commits, Changeset will collect these files to determine which package to bump, versioning, create changelogs, and publish package to registry automatically. The only manual work is writing a change file.

Pre-release version

Semantic version has pre-release version specs for an unstable build. The format is something like this 1.0.0-alpha, 1.0.0-alpha.1 in my case is 0.1.0-beta.1

The problem

Everything seems fine. I setup changesets. Make a first changes. Write a changesets file. Push commit to remote. Pipeline run. Changesets tags and push 0.1.0-beta.1 to private registry. Everything works as expected. Nothing to worry. I work on other work.

Sometime later. I make an another change. Push commit to remote.

Pipeline GREEN. But I notice something in the CI log.

🦋  info npm info @nitpum/ui
🦋  warn Received 404 for npm info "@nitpum/ui"
🦋  info @nitpum/ui is being published because our local version (0.1.0-beta.1) has not been published on npm

Look like changesets can’t find my package on the registry and try to publish 0.1.0-beta.1 to the registry again because it think this version never published and this is the first times.

But how it can’t find the existing version?

After some investigation, I found that changesets use npm info underlying.

What is npm info

npm info is a command to get package information e.g. description, dependencies, dist-tags, etc. The command is same as npm view

npm info <package-name>

Changesets Implementation

Changesets implemented code like this

 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
let result = await spawn("npm", [
	"info",
	packageJson.name,
	"--registry",
	getCorrectRegistry(packageJson),
	"--json",
]);

// Github package registry returns empty string when calling npm info
// for a non-existent package instead of a E404
if (result.stdout.toString() === "") {
	return {
		error: {
			code: "E404",
		},
	};
}
return jsonParse(result.stdout.toString());

Changesets check the stdout if returns empty, assume that it run on Github actions and package not exists. Normally, npm info never returns empty string on stdout.

But these is a case that can returns empty string.

If your package is published pre-release version and never published stable version yet, Looks like the registry can’t get package info because no info from stable version so it returns empty string instead (package info is empty)

Not sure that all registry has this problem. In my case the registry is SonarType Nexus

The solution

Publish a stable version to registry once then npm info will return package info with pre-release version info correctly, instead of empty string.

Support me on Ko-fi
Share
Twitter Tweet
Make lint-staged + eslint work in monorepo

Make lint-staged + eslint work in monorepo

• 2 min