santifer/career-ops · error · Error
apply session not found
Error message
apply session not found
What it means
Thrown by `handoffSession` when the requested `id` is missing from the `SESSIONS` map — same root cause as the fillSession case but at the final 'hand the filled form to the human' step. After filling, the code repositions the browser window on-screen via CDP and calls `bringToFront`; both require a live session, so a missing one is fatal before any UI work begins.
Source
Thrown at web/src/lib/apply/session.ts:524
const endPath = (() => {
try {
return new URL(s.frame.url()).pathname;
} catch {
return s.frame.url();
}
})();
// Read the real form back: did every answer actually land? any validation
// error? — so we warn the user about silent divergence before the handoff.
const issues = await verifyFill(s.frame, fieldsMeta, answers).catch(() => [] as ApplyIssue[]);
return { steps, navigated: endPath !== startPath, issues };
}
/** Hand the real (now pre-filled) form to the HUMAN to review + submit. The
* window was kept OFF-SCREEN during fill, so bringToFront alone wouldn't make it
* visible — we reposition it on-screen via CDP first. We never submit. */
export async function handoffSession(id: string): Promise<void> {
const s = SESSIONS.get(id);
if (!s) throw new Error("apply session not found");
try {
const cdp = await s.context.newCDPSession(s.page);
const { windowId } = (await cdp.send("Browser.getWindowForTarget")) as { windowId: number };
await cdp.send("Browser.setWindowBounds", {
windowId,
bounds: { left: 80, top: 60, width: 1280, height: 920, windowState: "normal" },
});
await cdp.detach().catch(() => {});
} catch {
/* CDP unavailable → bringToFront still raises it */
}
await s.page.bringToFront().catch(() => {});
}
View on GitHub (pinned to 9b17a8ac97)
Solutions
- Reopen the session (`openSession`) and re-`fillSession` before retrying handoff — handoff is meaningless without a filled, live form.
- Surface this in the UI as 'your session expired — please reopen the application' rather than a raw error.
- Chain open → fill → handoff as one continuous flow with no long pauses so the idle pruner can't fire.
- Track whether handoff already succeeded to make the operation idempotent and prevent duplicate triggers.
- If idle expiry is too aggressive for your users, extend the prune threshold.
Example fix
// before
await handoffSession(staleId); // throws 'apply session not found'
// after — ensure a live, filled session first
const s = SESSIONS.has(id) ? { id } : await openSession(url);
await fillSession(s.id, answers, fields);
await handoffSession(s.id); Defensive patterns
Strategy: retry
Validate before calling
// Only hand off a known-live, filled session.
async function safeHandoff(id, url, answers, fields) {
if (!SESSIONS.has(id)) {
const fresh = await openSession(url);
await fillSession(fresh.id, answers, fields);
return handoffSession(fresh.id);
}
return handoffSession(id);
} Try / catch
try { await handoffSession(id); }
catch (e) {
if (/not found/i.test(e.message)) {
const fresh = await openSession(url);
await fillSession(fresh.id, answers, fields);
await handoffSession(fresh.id);
} else throw e;
} Prevention
- Make handoff idempotent: track a 'handedOff' flag per id and skip if already done.
- Open → fill → handoff in one continuous flow.
- On dev server hot-reload, clear UI references to stale session ids.
- Surface 'session expired — reopen' to the user rather than the raw error.
When it happens
Trigger: Calling `handoffSession(id)` after the session was pruned, after the process restarted, with a typo'd id, or after the session was already handed off / closed. The CDP window-reposition and `bringToFront` calls never execute because the guard fails first.
Common situations: User left the filled form open overnight (idle pruner cleared it); dev server restart lost in-memory state; UI re-issues handoff after a successful one; double-click on a 'review & submit' button; session closed elsewhere in a multi-tab flow.
Related errors
- apply session not found (it may have expired)
- The apply feature needs Google Chrome. Install Chrome (or ru
- ${msg}
AI-assisted analysis of santifer/career-ops@9b17a8ac97 (2026-08-13).
Data as JSON: /api/errors/04ecb614ba9d8044.
Report an issue: GitHub.