paperclip/tests/e2e
Devin Foley 61a5b7c6f9
fix(ui): stop the selection ping-pong on archived company URLs (#11300)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - The UI keeps a selected company in `CompanyProvider` with two
writers: a bootstrap effect that repairs invalid selections, and a
Layout route-sync effect that selects the company the URL prefix names
> - The route-sync matches the URL against the full company list
(archived included), while the bootstrap resolver only accepted
companies from the sidebar-filtered non-archived list
> - On any archived company's URL the two effects overwrite each other's
selection in a synchronous loop until React throws error #185 ("Maximum
update depth exceeded") and unmounts the root to a blank page — armed by
remembered last-visited paths, back/forward navigation, or bookmarks, on
first load and client navigation alike
> - This pull request makes an already-selected company only need to
exist, keeping the sidebar filter for fresh-boot resolution where no
explicit selection exists
> - The benefit is that archived company URLs render instead of blanking
the entire app

## Linked Issues or Issue Description

No existing issue. Description follows the bug template:

**What happened?**

Opening (or back-navigating to) a URL whose company prefix belongs to an
archived company blanked the whole app with `Minified React error #185`.
Console in dev mode: "Maximum update depth exceeded. This can happen
when a component calls setState inside useEffect…". A workspace whose
first/seeded company was archived hit this on every load of its
remembered URL.

**Expected behavior**

An archived company's URL renders its pages (the company still exists
and its API routes serve data). The sidebar simply does not feature
archived companies, and fresh boots still land on a non-archived
company.

**Steps to reproduce**

1. Create two companies; archive one (`PATCH /api/companies/:id` with
`status: "archived"`).
2. Navigate to `/{archivedPrefix}/dashboard` — direct load or
client-side back-navigation.
3. Before this fix: React #185 and an unmounted blank page (reproduced
deterministically by the new e2e test).

## What Changed

- `ui/src/context/CompanyContext.tsx`:
`resolveBootstrapCompanySelection` keeps an explicitly selected company
that exists in the full company list; stored-id and default resolution
still prefer sidebar (non-archived) companies.
- `ui/src/context/CompanyContext.test.tsx`: resolver keeps an
archived-but-existing selection; a truly deleted selection is still
replaced.
- `tests/e2e/archived-company-url.spec.ts`: end-to-end regression
driving both field shapes (direct load and back-navigation onto an
archived company URL); it failed with the exact #185 console errors
before the fix and passes after.

## Verification

- `pnpm vitest run src/context …` in `ui/` — 122 tests pass (includes
the new resolver cases).
- `npx playwright test --config tests/e2e/playwright.config.ts
archived-company-url` — fails before the fix (captured "Maximum update
depth exceeded" console errors), passes after.
- `pnpm typecheck` in `ui/` — clean.

## Risks

Low risk. The only behavioral change is that a selection naming an
archived-but-existing company survives the bootstrap repair — previously
that state was unreachable without crashing. Boots with no valid
selection behave exactly as before (non-archived preferred), covered by
the existing and new resolver tests.

## Model Used

- Claude (Anthropic), Claude Fable 5 (`claude-fable-5`), via Claude Code
CLI with extended thinking and tool use (code search, edit, test
execution, Playwright-driven crash reproduction).

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [ ] All Paperclip CI gates are green
- [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge
2026-08-12 15:40:33 -07:00
..
helpers feat: make chat-style tasks the default experience (#11101) 2026-08-11 09:06:21 -07:00
app-not-connected.spec.ts feat(apps): support multiple provider connections (#11060) 2026-08-07 16:28:04 -05:00
application-delete-screenshot.spec.ts feat(connections): add v3 schema core (#9958) 2026-07-21 15:16:26 -05:00
applications-crud.spec.ts feat(apps): support multiple provider connections (#11060) 2026-08-07 16:28:04 -05:00
apps-dark-mode-shots.spec.ts feat: refine app connections and legacy worktree startup (#11040) 2026-08-07 14:26:40 -05:00
apps-prosumer-mcp-flow.spec.ts feat: refine app connections and legacy worktree startup (#11040) 2026-08-07 14:26:40 -05:00
archived-company-url.spec.ts fix(ui): stop the selection ping-pong on archived company URLs (#11300) 2026-08-12 15:40:33 -07:00
conference-room-typing-intro.spec.ts feat: make chat-style tasks the default experience (#11101) 2026-08-11 09:06:21 -07:00
fetch-allowed-port.ts feat(mcp) [split 8/8]: add e2e coverage and operator docs (#9563) 2026-07-14 15:48:57 -05:00
mcp-user-stories.catalog.ts feat(mcp) [split 8/8]: add e2e coverage and operator docs (#9563) 2026-07-14 15:48:57 -05:00
mcp-user-stories.spec.ts feat: refine app connections and legacy worktree startup (#11040) 2026-08-07 14:26:40 -05:00
multi-user-authenticated.spec.ts feat: implement multi-user access and invite flows (#3784) 2026-04-17 09:44:19 -05:00
multi-user.spec.ts feat: implement multi-user access and invite flows (#3784) 2026-04-17 09:44:19 -05:00
nux-phase4-screenshots.spec.ts feat: make chat-style tasks the default experience (#11101) 2026-08-11 09:06:21 -07:00
onboarding.spec.ts feat: make chat-style tasks the default experience (#11101) 2026-08-11 09:06:21 -07:00
pipelines-tutorial-flow.spec.ts test: port pipelines tutorial e2e (#9149) 2026-07-07 05:54:26 -05:00
planning-mode-visual-verification.spec.ts feat: make chat-style tasks the default experience (#11101) 2026-08-11 09:06:21 -07:00
playwright-multiuser-authenticated.config.ts feat: implement multi-user access and invite flows (#3784) 2026-04-17 09:44:19 -05:00
playwright-multiuser.config.ts feat: implement multi-user access and invite flows (#3784) 2026-04-17 09:44:19 -05:00
playwright.config.ts feat(decisions): add first-class propose mode (#10010) 2026-07-31 19:17:02 -07:00
sidebar-takeover.spec.ts feat: make in-app features cloud-aware (#10850) 2026-08-04 23:00:14 -05:00
signoff-policy.spec.ts feat(issues): contain cross-issue agent side effects (#10837) 2026-08-04 13:17:49 -05:00
smoke-lab-browser-runner.mts feat(connections): add v3 schema core (#9958) 2026-07-21 15:16:26 -05:00
smoke-lab-routine-classifier.test.mts feat(mcp) [split 8/8]: add e2e coverage and operator docs (#9563) 2026-07-14 15:48:57 -05:00
smoke-lab-routine.mts feat(mcp) [split 8/8]: add e2e coverage and operator docs (#9563) 2026-07-14 15:48:57 -05:00
smoke-lab.catalog.ts feat(connections): add v3 schema core (#9958) 2026-07-21 15:16:26 -05:00
smoke-lab.spec.ts feat: refine app connections and legacy worktree startup (#11040) 2026-08-07 14:26:40 -05:00