Bug: Inconsistent return value in fetchGitHubRepos
File: server/utils/githubAnalyzer.js:118-151
Problem
fetchGitHubRepos returns two different shapes depending on cache state:
When cached (line 120):
return cached; // returns the simplified repos array directly: [{ name, description, ... }]
When not cached (line 150):
return { repos: simplified }; // returns { repos: [...] }
Impact
The caller at line 190 does:
const { repos, error } = await fetchGitHubRepos(username);
When cached, this destructures the array — repos becomes undefined and error becomes undefined. The check if (error || !repos || repos.length === 0) evaluates to true (because !undefined), so cached profiles are always treated as errors with message 'No repos'.
Fix
Make the return shape consistent. Cache the wrapper object:
async function fetchGitHubRepos(username) {
const cached = getCached(`repos:${username}`);
if (cached) return cached;
// ... fetch ...
const result = { repos: simplified };
setCached(`repos:${username}`, result);
return result;
}
Severity
High — GitHub analysis completely breaks for any username that has been cached (after first fetch, all subsequent fetches within 1hr TTL return wrong results).
Phase
Introduced in Phase 3 (PR #28, merged). Also present in Phase 4 tests (PR #29).
Bug: Inconsistent return value in fetchGitHubRepos
File:
server/utils/githubAnalyzer.js:118-151Problem
fetchGitHubReposreturns two different shapes depending on cache state:When cached (line 120):
When not cached (line 150):
Impact
The caller at line 190 does:
When cached, this destructures the array —
reposbecomesundefinedanderrorbecomesundefined. The checkif (error || !repos || repos.length === 0)evaluates totrue(because!undefined), so cached profiles are always treated as errors with message 'No repos'.Fix
Make the return shape consistent. Cache the wrapper object:
Severity
High — GitHub analysis completely breaks for any username that has been cached (after first fetch, all subsequent fetches within 1hr TTL return wrong results).
Phase
Introduced in Phase 3 (PR #28, merged). Also present in Phase 4 tests (PR #29).