Environment
- Fresh clone of
nexu-io/html-anything
pnpm install
pnpm build
pnpm start
- Next.js
16.2.6
- React
19.2.4
- Codex CLI via
codex exec --json
Symptoms
1. Layout-dependent React hook order crash
Chrome showed the Next error page with minified React error #300.
Local fix:
src/components/convert-chip.tsx
ConvertChip returned early when layoutMode !== "split", before later useCallback and useEffect hooks. Moving that conditional return after all hooks keeps hook order stable across layout changes.
2. React external store snapshot loop
Chrome showed the Next error page with minified React error #185.
Development mode expanded it to:
The result of getSnapshot should be cached to avoid an infinite loop
Maximum update depth exceeded
Local fix:
src/components/deploy-control.tsx
The Zustand selector used this fallback:
selectActiveTask(s)?.deployments ?? []
That creates a fresh array for each snapshot when a task has no deployments. A module-level stable fallback fixes the loop:
const EMPTY_DEPLOYMENTS: DeploymentRecord[] = [];
const deployments = useStore(
(s) => selectActiveTask(s)?.deployments ?? EMPTY_DEPLOYMENTS,
);
3. Codex CLI exits successfully while generated HTML stays empty
The app log showed:
INFO 准备调用 codex · 模板 ppt-keynote · 输入 473 字符 (markdown)
START spawn …/codex · prompt 4.8 KB
DONE agent 进程退出 (exit=0)
The preview stayed empty with Size 0.0 KB.
A minimal CLI run shows the current Codex JSON output shape:
{"type":"item.completed","item":{"id":"item_0","type":"agent_message","text":"<html><body>ok</body></html>"}}
{"type":"turn.completed","usage":{"input_tokens":31365,"cached_input_tokens":3456,"output_tokens":14,"reasoning_output_tokens":0}}
Current parser path in src/lib/agents/argv.ts expects the older shape:
item.item_type === "assistant_message"
obj.type === "task_complete"
Local fix:
const item = obj.item as { item_type?: string; type?: string; text?: string };
if (
(item.item_type === "assistant_message" || item.type === "agent_message") &&
typeof item.text === "string"
) {
out.push({ kind: "delta", text: item.text });
}
if ((obj.type === "task_complete" || obj.type === "turn.completed") && obj.usage) {
out.push({ kind: "meta", key: "usage", value: obj.usage });
}
Verification
After applying the three local fixes:
pnpm build succeeds
localhost:3000 returns 200 OK
- Chrome renders the main HTML Anything UI
- Codex CLI output is parsed from
item.type === "agent_message"
Environment
nexu-io/html-anythingpnpm installpnpm buildpnpm start16.2.619.2.4codex exec --jsonSymptoms
1. Layout-dependent React hook order crash
Chrome showed the Next error page with minified React error
#300.Local fix:
src/components/convert-chip.tsxConvertChipreturned early whenlayoutMode !== "split", before lateruseCallbackanduseEffecthooks. Moving that conditional return after all hooks keeps hook order stable across layout changes.2. React external store snapshot loop
Chrome showed the Next error page with minified React error
#185.Development mode expanded it to:
Local fix:
src/components/deploy-control.tsxThe Zustand selector used this fallback:
That creates a fresh array for each snapshot when a task has no deployments. A module-level stable fallback fixes the loop:
3. Codex CLI exits successfully while generated HTML stays empty
The app log showed:
The preview stayed empty with
Size 0.0 KB.A minimal CLI run shows the current Codex JSON output shape:
{"type":"item.completed","item":{"id":"item_0","type":"agent_message","text":"<html><body>ok</body></html>"}} {"type":"turn.completed","usage":{"input_tokens":31365,"cached_input_tokens":3456,"output_tokens":14,"reasoning_output_tokens":0}}Current parser path in
src/lib/agents/argv.tsexpects the older shape:Local fix:
Verification
After applying the three local fixes:
pnpm buildsucceedslocalhost:3000returns200 OKitem.type === "agent_message"