Repository navigation
Destroyed-object and frame-targeting contract #426
Description
Activity
- addedwayfinder:researchWayfinder research decisionWayfinder research decisionelectron-compatElectron compatibility program areaElectron compatibility program area
on Oct 6, 2026 Generated by an AI agent (Claude Code, Fable 5.1) on behalf of @0monish during Wayfinder charting of the Electron compatibility program, 2026-10-06. Evidence-backed; every resolved decision was taken under explicit user delegation and cites its sources. Planning only — no implementation is authorized by this issue.
Resolution
Facade objects are host-minted (handle, generation) pairs. The tombstone flips BEFORE 'closed' is emitted (isDestroyed() true inside a closed listener); later member access throws the exact 'Object has been destroyed' text synchronously; destroy() skips close/beforeunload and guarantees closed. webContents.send targets the current main frame (delivered after navigation, throws after destruction); event.reply/senderFrame.send bind to the sender's document and go stale after navigation; senderFrame may be null. draw.io's 24 event.reply sites ride the frame-targeted path and its validateSender tolerates null.
Evidence
- [fact] scratchpad/base_window.cc:165-184 WillCloseWindow Emit('close')→prevent_default; OnWindowClosed: MarkDestroyed() → FlushWindowState() → Emit('closed') (v44.4.5)
- [fact] scratchpad/browser-window.v44.4.5.md:519 'throws Object has been destroyed'; :662 destroy 'guarantees the closed event will be emitted'
- [fact] ipc-main-event.md v44.4.5 senderFrame 'May be null if accessed after the frame has either navigated or been destroyed' (fetched 2026-10-06)
- [fact] web-frame-main.md v44.4.5 'it may become detached as the newly navigated page replaced it in the frame tree' (fetched 2026-10-06)
- [fact] grep -rF '.reply(' drawio-desktop/src = 24 (all main/electron.js); electron.js:692-700 validateSender returns false on null frame
- [inference] exact throw text on webContents.send after destruction is from the shared destroyed-wrapper check, not a fixture run
Resolved autonomously under the user's delegation (map Notes); reopen by comment if evidence contradicts this.
Parent map: #391 · Unit: perspective panel (8 isolated personas → cross-critique → 3 judges) · Wayfinder type:
researchQuestion
Destroyed-object and frame-targeting contract
Summary
Facade objects are host-minted (handle, generation) pairs. The tombstone flips BEFORE 'closed' is emitted (isDestroyed() true inside a closed listener); later member access throws the exact 'Object has been destroyed' text synchronously; destroy() skips close/beforeunload and guarantees closed. webContents.send targets the current main frame (delivered after navigation, throws after destruction); event.reply/senderFrame.send bind to the sender's document and go stale after navigation; senderFrame may be null. draw.io's 24 event.reply sites ride the frame-targeted path and its validateSender tolerates null.
Evidence
Context
Raised by the eight-persona perspective panel (isolated positions → cross-critique → three judges); judge extracts and persona positions are on the research branch (
wayfinder/electron-compat/panel/).