AntFleet

Disagreement · 24879b45-anthropic-0

RSS feed crashes when a cross-repo merged row has null mergedAt (type lies)

mismatch
repo e24ef98c·PR #10·reviewed 1 week ago

Primary finding

RSS feed crashes when a cross-repo merged row has null mergedAt (type lies)

mediumbugmedium
  • apps/web/app/receipts.rss/route.ts:39-49
  • apps/web/lib/receipts.ts:117-145
The CrossRepoReceiptRow type declares mergedAt: Date (non-null) and mapMergedRowsToReceipts filters out rows with null mergedAt, so under normal operation the RSS handler's r.mergedAt.getTime() call in the .toSorted comparator is safe. However, the sort comparator uses pubDate.getTime() — for same-repo items the type asserts closedAt: Date (filtered via `r.closedAt !== null`), and for cross-repo it requires Date. This is consistent so no immediate bug, but worth verifying the row guarantees hold.

Recommendation

No change needed; the guards in mapMergedRowsToReceipts and the same-repo filter in route.ts maintain the Date invariant. Consider adding a runtime assertion in mapMergedRowsToReceipts to log when a row is dropped to detect schema drift.

Counterpart finding

Potential runtime incompatibility: use of Array.prototype.toSorted in Node.js route

mediummaintainabilitymedium
  • apps/web/app/receipts.rss/route.ts:47-49
Array.prototype.toSorted is a relatively new addition (ES2023) and is not available on Node.js 18, which is still common in Next.js deployments unless explicitly set to Node 20+. Next.js does not polyfill built-in prototype methods on the server runtime. If this route executes on a Node < 20 runtime, it will throw TypeError: items.toSorted is not a function, breaking the RSS endpoint.

Recommendation

Replace toSorted with a backward-compatible pattern that does not mutate input: - const items = [...sameRepoItems, ...crossRepoItems].sort((a, b) => b.pubDate.getTime() - a.pubDate.getTime()); This works on all supported Node versions and preserves the non-mutating intent by sorting a copy.

Why this didn't post

This finding didn't meet AntFleet's unanimous agreement threshold. Both frontier models review every PR independently; only findings they both flag with the same severity and category are posted to the PR. This one fell through.

read the methodology →