npm 整顿代码圈:只按美国作息上班,逼你上夜班

0 阅读1分钟

本篇话题 pnpm/pnpm npm 410 Gone 2026-04-15

一句话 全世界的开发者那几天发现自己的程序半夜自己崩了,以为是自己坏了 —— 其实是有个服务按计划关掉了,而它一天只开 12 个小时,且只开在美国上班时间。

原始报告 github.com/pnpm/pnpm/issues/11265 · github.com/yarnpkg/yarn/issues/9234

各位老哥,今天这个瓜我得说一句:这是本系列最安静的一种出事方式。

上一篇好歹还有人认了错。这个,从头到尾没有一个人做过什么坏事。

没有人在半夜偷偷下手。没有人在群里发坏话。没有人在代码里下毒。

就是有人做了一个决定,按计划执行了,然后继续上班。

而这个决定的形状是:它一天只开 12 个小时,且这 12 小时正好是美国上班时间。

各位老哥,你们品品这个形状。

它不是坏了。它是按时上下班。

而亚洲和欧洲的人,正好都在它下班的时候需要它。

先把这件事讲明白

不提术语。就一句话:

你去一家馆子吃饭,结果发现它只在中午 12 点到晚上 12 点开门。

你上午十一点到,晚上八点还饿着。

你会骂这馆子吗?你会报警吗?

你大概只会说一句:「那我去别家。」

问题是:那家馆子不是你开的。而且你不知道它什么时候开始这么营业的,也没有任何一张纸告诉你它中午关门。

2026 年 4 月 15 日凌晨,好几万个程序员同时遇上了这件事。

他们做的是同一件事:顺手检查一下自己的软件有没有安全漏洞。

检查的工具是免费网站 npm 提供的。npm 就是全世界上下载开源代码包最多的那个地方, 连 Linux 上装个软件的默认命令都是从它那儿取东西。

那天凌晨,npm 把这项服务按计划关掉了。

不是彻底关。是每天开一会儿。

每天大约 12 小时。且那 12 小时,正好是美国的工作时间。

现场

项目 npm(全网下载量最大的开源包仓库)· pnpm 36,833 ★ · yarn 41,469 ★ · dependency-check 7,737 ★(2026-10-18 亲测)

谁做的决定 npm 的母公司,微软旗下的那家公司。

理由呢?

他们从来没在公开渠道说过。

不是「说了但没人注意」,是一个字都没有。 那封两周后由第三方转贴出来的私信里,也只讲了什么时候关,没讲为什么关。

谁在买单

同一天早上,几个互不相识的人发现自己的流程红了:

  • 一个用 pnpm 的人
  • 一个用 Yarn 1 的人
  • OWASP —— 全世界最有名的免费开源安全扫描项目,一分钱不要、连账号都不用注册的那种
  • 美国卫生部的公开项目
  • Arista Networks —— 一家做网络设备的上市公司

这五家,没有一家提前知道。

事先有任何通知吗

没有。

npm 从头到尾没有发过一条公告。 连「哪天真会彻底关」这个日子,都是两周以后,有人去问客服才拿到的。

而且那句话出自一封私聊,不是任何公开公告。

一、凌晨那一下

2026 年 4 月 15 日 00:39:51,UTC。

一个叫 leonmeka 的人开了个单子,说他的程序半夜跑不动了。

9 个小时后,UTC 09:33:36。

另一个叫 jamgregory 的人开了第二个单子。他属于那个被全行业默认「不会出事」的一方 —— Yarn 本身。

他第一句话,逐字:

I imagine this won't be fixed (unfortunately), but it looks like npm has silently deprecated the security audit API that Yarn 1 uses

(我猜这个不会被修了(很遗憾),但看起来 npm 悄悄地废弃了 Yarn 1 用的那个安全检查接口。)

「悄悄地」这三个字,是整件事的题眼。

同一天上午 05:01:17,OWASP 的 roman-stoffel 也开了单子。

到这里为止,三份单子,三个团队,同一天,说的同一件事。

没有一个人收到过通知。

二、第二天:它又好使了

接下来的 39 个小时是这场瓜最拧巴的部分。

4 月 16 日 07:25:43,jamgregory 回到自己的单子,把昨天写的一段话用删除线划掉了,补了一句新的。逐字:

As of 10:50am (BST), the API is down again 😭

(英国时间上午 10:50,那个接口又挂了。)

15:01:00,一个叫 Pankeking 的人回了句:

it is working again 🥳

(又能用了 🎉)

又过了 43 分钟。

15:44:08,jamgregory 又来了。这条是全篇最关键的一段,逐字:

It's going to be interesting to see what happens tomorrow. It appears to be online for ~12 hours a day, but those hours are definitely coinciding with the US working day and not anyone else 😭

(明天会发生什么很有意思。它看起来每天只开大约 12 个小时,而且那 12 小时肯定正好是美国的工作日,不是别人的。)

他把那 12 小时是什么,说清楚了。

他当时还不知道原因。

三、他们说了,但也只是「说给说了的人」

前面这些事之所以没人知道,是因为外面根本没有可知道的东西。

npm 的公开渠道里,关于这次停掉,一个字都没有。 不是「发了公告没人看」,是没有公告。

而在那三份单子的评论区里,一位在 OWASP 负责的人(chadlwilson) 在 2026 年 4 月 16 日 13:08:03 写下了这段,逐字:

Yeah, this has taken down all scanning from OWASP dependency check for all NPM versions all PNPM versions Yarn Classic/v1 users We knew the legacy APIs were probably deprecated, but we don’t have the resources of trillion dollar companies like Microsoft nor commercial providers and there was no public deprecation whatsoever - so no idea how they expect people to know their intent in advance and marshall resources.

(是的,这把 OWASP dependency check 的扫描全部打挂了 —— 所有 npm 版本、 所有 pnpm 版本、Yarn Classic/v1 的用户。 我们知道那些老接口大概已经被废弃了,但我们没有万亿美元公司那种资源、 也没有商业供应商那种资源,而且从来就没有过任何公开的弃用声明 —— 所以完全不知道他们希望人们怎么提前知道他们的打算、怎么提前准备好人手。)

第一句是现场,第二句是结构。

第二句才是这篇的题眼。

注意他说的不是「我们没准备」,他说的是 「没有公开的弃用声明」。

不是他们没能力准备。是没有任何渠道告诉他们要准备。

而 npm 那句唯一漏出来的口径,从头到尾没给理由 —— 只讲了什么时候关、关到什么程度、能不能临时恢复。 一句「为什么」都没有。

四、官方说了 —— 但只对一个人说了

4 月 16 日 07:24:06,jamgregory 去了 npm 自己的仓库,开了一个单子。

标题逐字:

[BUG] Document missing audit endpoints and specify deprecation details

([BUG] 请补上没写进文档的那些审计接口,并写明弃用细节)

他没有骂人,没有指责,只是要求把该写的写上。

这个单子开了 12 天,没有回。

然后到了 4 月 28 日 00:22:56。

一个叫 fz-ryanbigg 的人,把一封私人客服邮件的原文贴了出来。

📌 这个人的账号所属组织是 @fatzebra,不是 npm,也不是 GitHub 的员工。 他只是个代为转述的第三方。

From GH support: Thanks for reaching out. I can confirm that the 410s you saw line up with a scheduled brownout for the legacy npm audit endpoints that Yarn v1 calls. … During the brownout window you can see errors like 410, and after July 15, 2026 the old endpoints will be fully retired. We are not able to bring the old endpoint back up temporarily.

(来自 GitHub 客服: 感谢您的联系。我可以确认,您看到的那些失败,与 Yarn v1 所调用的旧 npm 审计接口 一次计划内的临时停用相吻合。……在停用期间,您会看到类似 410 的错误, 并且在 2026 年 7 月 15 日之后,那些旧接口将被彻底退役。 我们无法临时把旧接口重新启用。)

各位老哥,这一拍才是整件事的核心。

npm 不是没解释。npm 解释得很清楚。

但这句话是发给一封私人邮件的。

而且它是两周以后,才由一个不相干的人,替他们传出去的。

所以从外面看,npm 从头到尾一言不发。

它其实一直在说。只是说给那一个愿意去私信客服的人听。

五、7 月 15 日

按那封邮件的说法,2026 年 7 月 15 日之后,旧接口彻底退役。

那一天发生了什么?

社区里有人当天贴出了一个绕行方案 —— 一段脚本,帮你绕开那个已经「退役」的接口。

到这一天为止,用户还在为它找 workaround。

前一天,也就是 7 月 10 日,社区里还有人说:

We're still waiting for an official response. 👍 4

(我们还在等一个官方答复。👍 4)

然后是 9 月 14 日。

GitHub 的机器人给那个单子打上了一个标签:

🕒 Discussion Activity Reminder 🕒 This Discussion has been labeled as dormant by an automated system for having no activity in the last 60 days.

(这个讨论已被自动系统标记为长期无人活动,因为它 60 天里没有任何动静。)

平台自己给这件事判了死刑。

从那天起,到今天(2026 年 10 月 18 日),零条官方回复。

六个月。

六、拉个表

时刻(UTC) / 发生了什么

  • 2026-04-15 00:39:51 —— 第一个人报:程序半夜跑不动了
  • 2026-04-15 05:01:17 —— OWASP 也报了
  • 2026-04-15 09:33:36 —— Yarn 那边说:「悄悄地废弃了」
  • 2026-04-15 23:47:07 —— pnpm 当天夜里修好了
  • 2026-04-16 07:24:06 —— Yarn 那个人去 npm 自己仓库要求「写进文档」
  • 2026-04-16 07:25:43 —— 他划掉自己前一天的话,补一句「又挂了」
  • 2026-04-16 15:01:00 —— 「又能用了 🎉」
  • 2026-04-16 15:44:08 —— 「每天只开 12 小时,而且正好是美国工作日」
  • 2026-04-28 00:22:56 —— 官方口径第一次公开露面,距事发 13 天
  • 2026-06-07 22:26:29 —— Yarn 那边:「No updates are planned for Yarn v1.」
  • 2026-07-10 16:02:15 —— 「还在等官方答复」(退役前一天)
  • 2026-07-15 19:08:14 —— 官方宣称彻底下线当天,仍有人在发绕行方案
  • 2026-09-14 00:59:49 —— 帖子被系统标为「长期无人活动」
  • 2026-10-18(今天) —— 零条官方回复

四个数字:

  • 39 小时 —— 第一个人报错,到有人说清那 12 小时是什么
  • 13 天 —— 事发,到官方口径第一次公开露面
  • 91 天 —— 事发,到官方宣称彻底下线那天(那天还在发绕行方案)
  • 139 天 —— 官方口径露面,到帖子被判死刑

七、这事最扎心的一句

写完这个 case,我卡在最后这一句上:

没有任何人滥用任何东西。没有人隐瞒任何事情。没有人在半夜偷偷下手。

偏偏就是这三句「没有」,把整件事定了性。

它只是有一个人在某个会议上算了一笔账,然后照着排期表,把一扇门在每天上班时间打开、其余时间关上。

而那 12 小时是哪个时区决定的,取决于那个开会的人在哪个时区。

前面几篇我写过:一道门跑偏了,一条判据被废了,一个门被堵死了, 三种死法,一个门忘了自己该重新评估。

这一篇是第四种,也是最普通的一种:门好好的,开门关门的人好好的, 一切都在按流程走 —— 流程里唯独没有「问一声外面的人」。

本篇不成立的结论

以下几条不能从本文推出去:

  1. 先说清楚:这不等于「npm 这家公司不行」,也不等于「停掉这个服务是错的」。

本文盯的是另一件事:一个只有内部排期表知道的决定,让外面五家机构同时崩了, 而他们连「什么时候会崩」都是从别人私信问来的。

  1. 也别读成「OWASP 这类项目反应过度」。 他们没有收到任何公开信息,

在没有通知的前提下,要求「提前知道」是最低限度,不是苛求。

  1. 推不出「npm 故意隐瞒」。 那句话确实存在于那封私信里,

只是没有走到公开渠道。 本文没有指控任何人故意不公开。

  1. 更写不得「npm 通知失败了」。 本文核到的是公开渠道没有任何公告 ——

这是「没发」,不是「发了没送到」。我没有核到任何一位受影响者 公开说过自己收到过通知却没收到二次提醒,所以这条不许推。

  1. 也别写「npm 从没跟任何人说过」。 那封私信确实存在,

而且内容准确(何时关、关到什么程度、不能临时恢复)。 问题是它只走了私信这条路。

  1. 别把这篇读成「开源不靠谱」。 真正的问题是同一个决定有两套通知机制:

内部排期表,和外部公告。只有前者有。

  1. 推不出「那 139 天里 npm 在做什么」。 帖子被判长期无人活动,

之后发生了什么没有公开记录,我不替它编动机。

附:本文引用

都是公开地址,不用登录。

  • 最早那份报告 → github.com/pnpm/pnpm/issues/11265
  • 说出「悄悄地废弃了」和「12 小时」的那份 → github.com/yarnpkg/yarn/issues/9234
  • OWASP 那份 → github.com/dependency-check/DependencyCheck/issues/8421
  • 要求「写进文档」、以及那封私信的转贴 → github.com/npm/api-documentation/issues/46
  • 最后被判长期无人活动的那份 → github.com/orgs/community/discussions/192768
  • 三家的仓库规模 → github.com/pnpm/pnpm、github.com/yarnpkg/yarn、

github.com/dependency-check/DependencyCheck

时间戳全部取自 GitHub 页面原始记录,精确到秒,都是 UTC。 所有引语逐字未改。所有天数都是本机算的。

📌 一条说明,别把它算进正文:pnpm 那个单子的时间线里, 中间有 27 条我取不出来(页面自己标着「27 remaining items」)。 本文对 2026-04-15 09:00 到 16:58 这段窗口不作任何断言, 也不说「那段时间没人说话」。缺的条目大概率是互相引用的链接,但那是推断。