I don't know how I ended up there, but it seems like I had a bad contributor profile stored in my IndexedDB. In order for others not also having to manually delete the database for the app to work again, let's just guard against the situation.
Problem
A contributor whose IPFS profile has no accounts array causes @kredits/contracts' ContributorSerializer.deserialize to throw → Contributor.getById rejects → the contributor never enters this.contributors → loadContributionFromData attaches contributor: undefined → UserAvatar throws Cannot read properties of undefined (reading 'github_uid') on render → the run-loop breaks and fetchMissingContributions / subsequent contribution loading stalls, so no further contributions are loaded.
Fix (app-side)
app/components/user-avatar/component.js: guard against this.contributor being undefined; added contributor to the computed's dependent keys so avatars re-render when a contributor is lazily loaded later.
app/services/kredits.js — kreditsByContributor: filter out groups whose contributor isn't loaded instead of dereferencing undefined.totalKreditsEarned.
app/services/kredits.js — new ensureContributorLoaded(id): called from loadContributionFromData and loadReimbursementFromData; fire-and-forget background fetch of the missing contributor, deduped via a contributorsFetching Set (added in init) so a tight loop over many contributions for the same missing contributor doesn't hammer the RPC. Rejections are logged, never thrown, so the run loop can't be broken by a persistently broken profile. On success, dependent computeds (kreditsByContributor, UserAvatar) retrigger via contributors.[].
Tests
tests/integration/components/user-avatar/component-test.js: undefined contributor; contributor without github_uid.
tests/unit/services/kredits-test.js: #kreditsByContributor with an orphan contribution referencing a non-existent contributor id (asserts no throw and no orphan entry in the toplist).
I don't know how I ended up there, but it seems like I had a bad contributor profile stored in my IndexedDB. In order for others not also having to manually delete the database for the app to work again, let's just guard against the situation.
### Problem
A contributor whose IPFS profile has no `accounts` array causes `@kredits/contracts`' `ContributorSerializer.deserialize` to throw → `Contributor.getById` rejects → the contributor never enters `this.contributors` → `loadContributionFromData` attaches `contributor: undefined` → `UserAvatar` throws `Cannot read properties of undefined (reading 'github_uid')` on render → the run-loop breaks and `fetchMissingContributions` / subsequent contribution loading stalls, so no further contributions are loaded.
### Fix (app-side)
- **`app/components/user-avatar/component.js`**: guard against `this.contributor` being undefined; added `contributor` to the computed's dependent keys so avatars re-render when a contributor is lazily loaded later.
- **`app/services/kredits.js` — `kreditsByContributor`**: filter out groups whose contributor isn't loaded instead of dereferencing `undefined.totalKreditsEarned`.
- **`app/services/kredits.js` — new `ensureContributorLoaded(id)`**: called from `loadContributionFromData` and `loadReimbursementFromData`; fire-and-forget background fetch of the missing contributor, deduped via a `contributorsFetching` Set (added in `init`) so a tight loop over many contributions for the same missing contributor doesn't hammer the RPC. Rejections are logged, never thrown, so the run loop can't be broken by a persistently broken profile. On success, dependent computeds (`kreditsByContributor`, `UserAvatar`) retrigger via `contributors.[]`.
### Tests
- `tests/integration/components/user-avatar/component-test.js`: undefined contributor; contributor without `github_uid`.
- `tests/unit/services/kredits-test.js`: `#kreditsByContributor` with an orphan contribution referencing a non-existent contributor id (asserts no throw and no orphan entry in the toplist).
refs #224
raucao
changed title from Guard dashboard against contributors that fail to load from IPFS to Guard dashboard against contributors failing to load correctly2026-07-26 11:24:35 +00:00
raucao
changed title from Guard dashboard against contributors failing to load correctly to Guard against contributors failing to load correctly2026-07-26 11:24:40 +00:00
raucao
merged commit 9054821e52 into master2026-07-26 11:24:46 +00:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
I don't know how I ended up there, but it seems like I had a bad contributor profile stored in my IndexedDB. In order for others not also having to manually delete the database for the app to work again, let's just guard against the situation.
Problem
A contributor whose IPFS profile has no
accountsarray causes@kredits/contracts'ContributorSerializer.deserializeto throw →Contributor.getByIdrejects → the contributor never entersthis.contributors→loadContributionFromDataattachescontributor: undefined→UserAvatarthrowsCannot read properties of undefined (reading 'github_uid')on render → the run-loop breaks andfetchMissingContributions/ subsequent contribution loading stalls, so no further contributions are loaded.Fix (app-side)
app/components/user-avatar/component.js: guard againstthis.contributorbeing undefined; addedcontributorto the computed's dependent keys so avatars re-render when a contributor is lazily loaded later.app/services/kredits.js—kreditsByContributor: filter out groups whose contributor isn't loaded instead of dereferencingundefined.totalKreditsEarned.app/services/kredits.js— newensureContributorLoaded(id): called fromloadContributionFromDataandloadReimbursementFromData; fire-and-forget background fetch of the missing contributor, deduped via acontributorsFetchingSet (added ininit) so a tight loop over many contributions for the same missing contributor doesn't hammer the RPC. Rejections are logged, never thrown, so the run loop can't be broken by a persistently broken profile. On success, dependent computeds (kreditsByContributor,UserAvatar) retrigger viacontributors.[].Tests
tests/integration/components/user-avatar/component-test.js: undefined contributor; contributor withoutgithub_uid.tests/unit/services/kredits-test.js:#kreditsByContributorwith an orphan contribution referencing a non-existent contributor id (asserts no throw and no orphan entry in the toplist).refs #224
Guard dashboard against contributors that fail to load from IPFSto Guard dashboard against contributors failing to load correctlyGuard dashboard against contributors failing to load correctlyto Guard against contributors failing to load correctly