From 1141f864906164b2a71e805c1f9df5ec268ab992 Mon Sep 17 00:00:00 2001 From: Ben Limmer Date: Wed, 27 May 2026 12:59:38 -0600 Subject: [PATCH] fix: guard against commit author with no login The GitHub REST "List commits" endpoint can return a non-null author object that has no login (an empty-object arm of the documented union, e.g. a deleted/anonymized account). Our hand-rolled ListCommitsItem type claimed login: string, so the truthy-author guard passed and author.login.endsWith('[bot]') threw an uncaught TypeError that crashed the scan. Make the type honest (login?: string) and skip authors without a login. Fixes PATCHWAVE-ANALYSIS-CLI-1 --- src/collectors/contributors.test.ts | 1 + src/collectors/contributors.ts | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/collectors/contributors.test.ts b/src/collectors/contributors.test.ts index 3969540..e854ffa 100644 --- a/src/collectors/contributors.test.ts +++ b/src/collectors/contributors.test.ts @@ -11,6 +11,7 @@ test('returns unique human committers, sorted, skipping bots', async () => { { author: { login: 'dependabot[bot]', type: 'Bot' }, commit: { author: { name: 'd', date: '' } } }, { author: { login: 'renovate[bot]', type: 'User' }, commit: { author: { name: 'r', date: '' } } }, { author: null, commit: { author: null } }, + { author: { type: 'User' }, commit: { author: { name: 'e', date: '' } } }, ]); const result = await listActiveCommitters(client, { owner: 'acme', name: 'widgets' }, '2026-01-01T00:00:00Z'); diff --git a/src/collectors/contributors.ts b/src/collectors/contributors.ts index 1902b4e..eba867e 100644 --- a/src/collectors/contributors.ts +++ b/src/collectors/contributors.ts @@ -4,7 +4,7 @@ import type { GithubClient } from '../github/GithubClient.ts'; import type { ContributorSlice, RepoRef } from '../types.ts'; interface ListCommitsItem { - author: { login: string; type?: string } | null; + author: { login?: string; type?: string } | null; commit: { author: { name: string; date: string } | null }; } @@ -24,7 +24,7 @@ export function listActiveCommitters( const logins = new Set(); for (const c of commits) { const author = c.author; - if (!author) continue; + if (!author?.login) continue; if (author.type === 'Bot') continue; if (author.login.endsWith('[bot]')) continue; logins.add(author.login);