Skip to content

Silence npm's update notice so the real error stays visible - #16

Merged
MickLesk merged 4 commits into
mainfrom
fix/npm-update-notifier
Sep 1, 2026
Merged

Silence npm's update notice so the real error stays visible#16
MickLesk merged 4 commits into
mainfrom
fix/npm-update-notifier

Conversation

@MickLesk

@MickLesk MickLesk commented Sep 1, 2026

Copy link
Copy Markdown
Member

✍️ Description

A failed install reported this:

in line 35: exit code 1: npm ci --workspace frontend
--- Last 20 lines of log ---
npm notice New major version of npm available! 11.19.0 -> 12.0.2
npm notice Changelog: ...
npm notice To update run: npm install -g npm@12.0.2

The notice is not the failure. npm prints it at the end of every run, so it occupies the tail of the log -- and the tail is exactly what the error excerpt shows. Three lines of advertising push out the three lines that would have explained why npm ci exited 1.

setup_nodejs now turns the notifier off, in the environment for the install itself and in the global npm config so it stays off for whoever works in the container later. 178 install scripts call it.

🔗 Related Issue

Fixes #

✅ Prerequisites (X in brackets)

  • Self-review completed – Code follows project standards.
  • Tested thoroughly – Changes work as expected (Proxmox VE and/or Incus, as applicable).
  • No security risks – No hardcoded secrets, unnecessary privilege escalations, or permission issues.
  • API.txt regenerated – If a function signature or behavior changed, API.txt was updated to match.

🤖 AI Assistance (X in brackets)

If you used an AI tool (GitHub Copilot, Claude, ChatGPT, etc.) to write or generate any code in this PR, you must confirm compliance below.
Select exactly one option.

  • No AI used – Code was written without AI assistance.
  • AI was used – The output has been reviewed and corrected, and I take responsibility for it matching this repo's conventions.

🛠️ Type of Change (X in brackets)

  • 🐞 Bug fix – Resolves an issue without breaking functionality.
  • New feature – Adds new, non-breaking functionality.
  • 💥 Breaking change – Alters existing behavior in a way that may require updates in every downstream script.
  • 🔧 Refactoring / Code Cleanup – Improves readability or maintainability without changing functionality.
  • 📝 Documentation update – Changes to README, docs/, CONTRIBUTING.md, or other docs.

A failed install reported this:

  in line 35: exit code 1: npm ci --workspace frontend
  --- Last 20 lines of log ---
  npm notice New major version of npm available! 11.19.0 -> 12.0.2
  npm notice Changelog: ...
  npm notice To update run: npm install -g npm@12.0.2

The notice is not the failure. npm prints it at the end of every run, so it
occupies the tail of the log -- and the tail is exactly what the error excerpt
shows. Three lines of advertising push out the three lines that would have
explained why npm ci exited 1.

setup_nodejs now turns the notifier off, in the environment for the install
itself and in the global npm config so it stays off for whoever works in the
container later. 178 install scripts call it.

Unrelated but checked while here: npm is pinned in exactly one place, the
npm@10.9.8 stepping stone for the Node 22.22.2 self-upgrade regression, and it
only fires when npm is exactly 10.9.7. The pnpm@11 and pnpm@10.33.0 pins in
five install scripts are pnpm, not npm.
Checked upstream. nodejs/node#62425 is closed since 2026-05-14: only 22.22.2
shipped npm 10.9.7, and 22.22.3 on 2026-05-13 went back to 10.9.8, as did
every 22.x since. A fresh install pulls 22.23.2 and never reaches this branch.

It is not dead code though -- it sits outside the install block, so it runs
whenever setup_nodejs is called, including on a container that already has
Node. What it repairs is a container built during the seven weeks 22.22.2 was
current. The comment now says that, with the condition for deleting it.

Also installs promise-retry first. The bug is that npm 10.9.7's arborist is
missing exactly that module, which is what people upstream found fixed it. The
pinned 10.9.8 step stays, since it succeeds where @latest on its own does not.
@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Try this branch

The engine and the scripts resolve independently, so a production script can
be run against the engine from this PR by setting one variable:

COMMUNITY_SCRIPTS_CORE_URL=https://raw.githubusercontent.com/community-scripts/core/fix/npm-update-notifier \
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/ct/debian.sh)"

Swap ct/debian.sh for whatever exercises the change.

Run a script from a fork as well
curl -fsSL https://raw.githubusercontent.com/community-scripts/core/fix/npm-update-notifier/tools/run.sh |
  bash -s -- https://raw.githubusercontent.com/YOU/ProxmoxVED/your-branch ct/debian.sh \
             https://raw.githubusercontent.com/community-scripts/core/fix/npm-update-notifier

Note that run.sh is reached through a pipe, so the script it starts inherits
an exhausted stdin. Whiptail is fine — it opens /dev/tty — but a plain read
would see EOF. The single-variable form above does not have that problem.

Useful flags while testing

dev_mode=net logs every engine fetch with status and duration, which is the
quickest way to confirm the branch is really being used. dev_mode=keep stops a
failed build from deleting the container along with the evidence.

The pin was belt and braces on top of a repair that does not need it. The bug
is a missing promise-retry in npm 10.9.7's arborist; supply that module and npm
upgrades itself normally, which is exactly what the upstream reporters did.
Stepping through 10.9.8 first only made sense while the cause was unclear.

No npm version is pinned in core now.
Nothing ever ran npm install -g npm. Install took whatever npm NodeSource had
bundled with that Node package, and the update path ran apt-get --only-upgrade
nodejs, which carries a newer npm only when Node itself moves. So a container
sat on months-old npm and npm advertised its own update on every run -- which
is how this started.

Both paths now bring npm to the newest release. It is a no-op when already
current, so the update path needs no separate version check.

One thing to weigh: npm@latest means an install picks up a new npm major on the
day it lands, and 178 install scripts run through here. NPM_VERSION pins it for
any script that a major breaks.
@MickLesk
MickLesk merged commit 11666dc into main Sep 1, 2026
4 of 5 checks passed
MickLesk added a commit that referenced this pull request Sep 1, 2026
It arrived in lib/runtime.func with #16 and the snapshot was not
regenerated, so "Each loader still defines its whole API" fails on main
and on every branch opened from it.
MickLesk added a commit that referenced this pull request Sep 1, 2026
* Report the exit code the engine actually saw

Four places were turning real information into "exit code 1, category
shell", which is why that pair sat at the top of the dashboard while
telling nobody anything.

post_update_to_api defaulted its code argument to 1 and mapped anything
non-numeric to 1. Both mean "no code was passed", which is not the same
fact as "the command returned 1" -- and 1 is what bash returns for every
ordinary failure, so the two were indistinguishable once written. They
now report 199, which says what happened.

The host read the container's code with `cat flag || echo "1"`, throwing
away a code it already had: lxc-attach's own return value, taken a few
lines earlier. It falls back to that now.

Codes 113, 114, 122, 253 and 254 are the engine asking a question and
being told no. They were filed as failures, so "exit 113" -- a user
declining an under-provisioned update -- was one of the largest single
signatures in the data, sitting under exit code 1. They join the signal
codes in reporting "aborted", and categorize_error agrees with that
branch so a run is not filed as one thing and described as another.

199 is added to both copies of the table: api/exitcodes.func and the
fallback in core/error_handler.func that containers use when api.func is
not loaded. The header pointed at docs/exit_codes.md for keeping them in
step, which does not exist; it now names what actually has to move.

* Stop attributing the engine's own repo to forks

Runs bootstrapped without COMMUNITY_SCRIPTS_URL fall through to scraping
/proc/$$/cmdline, and the bootstrap line names only the engine. So the
scrape finds "community-scripts/core", which matched no known repo and
landed in the fork branch: REPO_SOURCE=external, REPO_SLUG=
community-scripts/core.

That is not a fork. It gave the slug its own row on the dashboard --
4,451 runs, second only to ProxmoxVE itself -- and counted every one of
them as somebody else's code. core now joins the empty case and takes
the hardcoded fallback, which CI rewrites from VED to VE on promotion.

Method 0 already existed to prevent this and is untouched; these are the
runs where it does not apply.

* Report the exit code the engine actually saw

post_update_to_api defaulted its code argument to 1 and mapped anything
non-numeric to 1, so "no code was passed" and "the command returned 1"
became the same number -- and 1 is what bash returns for any ordinary
failure. Both now report 199.

The host read the container's code with `cat flag || echo "1"`, throwing
away lxc-attach's own return value taken a few lines earlier. It falls
back to that instead.

113, 114, 122, 253 and 254 are the engine asking a question and being
told no. Filing them as failures is why "exit 113" was one of the
largest signatures in the data, sitting under exit code 1. They now
report aborted, and categorize_error agrees.

199 is added to both copies of the table, including the container
fallback in core/error_handler.func.

* Stop attributing the engine's own repo to forks

Runs bootstrapped without COMMUNITY_SCRIPTS_URL fall through to scraping
/proc/$$/cmdline, where the bootstrap line names only the engine. The
scrape finds "community-scripts/core", which matched no known repo and
landed in the fork branch as REPO_SOURCE=external.

That gave the slug its own row on the dashboard -- 4,451 runs, second
only to ProxmoxVE -- and counted them all as somebody else's code. core
now joins the empty case and takes the hardcoded fallback, which CI
rewrites from VED to VE on promotion.

* Add _setup_npm to the lib API snapshot

It arrived in lib/runtime.func with #16 and the snapshot was not
regenerated, so "Each loader still defines its whole API" fails on main
and on every branch opened from it.
@github-actions
github-actions Bot deleted the fix/npm-update-notifier branch September 2, 2026 06:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant