Summary
The Add Full Camera toolbar button and the C keyboard shortcut create a camera-fullscreen region on a project that has no webcam at all. The region is persisted, renders nothing forever, and the user gets no feedback.
The AI-agent path already refuses this exact action, so the app currently contradicts itself depending on which entry point you use.
Reproduction
- Import a plain video that has no camera track (
cameraTrack: null — any non-OpenScreen recording).
- Press
C, or click the Maximize2 button in the timeline toolbar.
Expected: the control is disabled, or the action is refused with an explanation — the way the agent does it.
Actual: a Full Camera pill appears in the lane and is persisted into legacyEditor.cameraFullscreenRegions. It renders nothing in preview and nothing in the export, permanently, with no indication why.
Why it renders nothing
PreviewCanvas.effectiveLayout short-circuits:
if (!layout?.webcamRect || cameraFullscreenProgress <= 0) return layout;
and the export path does the same. So the region is inert by construction — there is no webcam rect to grow to.
The inconsistency
electron/ai-edition/agent-tools.ts:208-226 already guards this and refuses verbatim:
…so a full-camera region there would render nothing and none was written… this recording has no webcam.
The two UI entry points have no gate at all:
src/components/ai-edition/v4/V4Timeline.tsx:1369
src/components/ai-edition/NewEditorShell.tsx:980
Suggested fix
Put the guard in the shared mutation rather than at each call site, so both entry points and any future one route through it — src/lib/ai-edition/store/useTimeline.ts:348:
if (!hasAnyClipWithCamera(document.assets, document.timeline.clips)) return;
hasAnyClipWithCamera already exists in src/lib/ai-edition/timeline/camera.ts and is the consolidated answer to "does this have a camera". Plus disabled on the toolbar button so the control is honest before it is clicked.
Context
Found while reviewing #310, which fixes the identical defect on the Layout pane (the webcam preset dropdown now shows "No Webcam" and hides the PiP-only controls for camera-less projects). This is the same bug on the sibling surface; #310 deliberately scoped itself to the Layout pane, so this is the follow-up.
Summary
The Add Full Camera toolbar button and the
Ckeyboard shortcut create a camera-fullscreen region on a project that has no webcam at all. The region is persisted, renders nothing forever, and the user gets no feedback.The AI-agent path already refuses this exact action, so the app currently contradicts itself depending on which entry point you use.
Reproduction
cameraTrack: null— any non-OpenScreen recording).C, or click theMaximize2button in the timeline toolbar.Expected: the control is disabled, or the action is refused with an explanation — the way the agent does it.
Actual: a Full Camera pill appears in the lane and is persisted into
legacyEditor.cameraFullscreenRegions. It renders nothing in preview and nothing in the export, permanently, with no indication why.Why it renders nothing
PreviewCanvas.effectiveLayoutshort-circuits:and the export path does the same. So the region is inert by construction — there is no webcam rect to grow to.
The inconsistency
electron/ai-edition/agent-tools.ts:208-226already guards this and refuses verbatim:The two UI entry points have no gate at all:
src/components/ai-edition/v4/V4Timeline.tsx:1369src/components/ai-edition/NewEditorShell.tsx:980Suggested fix
Put the guard in the shared mutation rather than at each call site, so both entry points and any future one route through it —
src/lib/ai-edition/store/useTimeline.ts:348:hasAnyClipWithCameraalready exists insrc/lib/ai-edition/timeline/camera.tsand is the consolidated answer to "does this have a camera". Plusdisabledon the toolbar button so the control is honest before it is clicked.Context
Found while reviewing #310, which fixes the identical defect on the Layout pane (the webcam preset dropdown now shows "No Webcam" and hides the PiP-only controls for camera-less projects). This is the same bug on the sibling surface; #310 deliberately scoped itself to the Layout pane, so this is the follow-up.