6.9 KiB
tags, created, status, category
| tags | created | status | category | |||||
|---|---|---|---|---|---|---|---|---|
|
2026-10-14 | resolved | incident |
Newsroom launch failure — root cause & fix (2026-10-14)
Symptom
"Newsroom won't launch." The desktop plugin showed a blank / failed frame.
Root cause
The backing server on port 3520 was simply not running — not a broken app.
The hermes-newsroom desktop plugin does not run the app; it only frames
http://127.0.0.1:3520/newsroom in an iframe. When nothing listens on 3520,
curl returns 000 (connection refused) and the frame renders failed/blank.
Three compounding factors made it look broken and kept it flapping:
- No autostart entry existed. Nothing started the 3520 server at login, so after any reboot / process exit it stayed down with no way to come back.
- Every "fix" I made was a plain background launch.
bash -lc 'npm run start &'andPopenwithout a session get reaped when theexecute_codekernel dies (or times out). Symptom each time: server up, then000again a few minutes later with changed node PIDs. This is a lifecycle artifact, not an app crash. - Mode was
fixture. Even when the server was up, it served bundled demo data (22 stories), so the app "worked" but looked empty/sample —liveSourcesdefaulted tofalsebecause noconfig/newsroom.local.jsonexisted.
Why it kept breaking (the real mechanism)
- No node/Next.js crash in the Windows Application event log (only an unrelated RazerCortex .NET error).
- Each manual launch inherited my kernel's session → killed on kernel reap.
- Only a launch in its own process group (the autostart
.cmd'sstart ""detachment, orstart_new_session=True) survives. Current listenernode.exe22228, parentcmd.exe(3988) from the launcher — independent of the kernel.
Fix applied
- Autostart — wrote
%APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup\hermes-newsroom.cmd:Pinning absolute node + next paths (PATH is not resolved at login). Verified by kill → confirm 000 → re-run the@echo off cd /d "C:\Users\fight\src\hermes-newsroom" start "" /min "C:\Users\fight\AppData\Local\hermes\tools\node-26.7.0-win32-x64\node.exe" "C:\Users\fight\src\hermes-newsroom\node_modules\next\dist\bin\next" start --hostname 127.0.0.1 --port 3520.cmd→ re-probe 200. - Live sources — wrote
config/newsroom.local.json(git-ignored) withliveSources: true, watchlists,socialSources.bluesky=false(Bluesky public API returns 403 from this box — bot-walled/region; left on it'd just show a provider-error line). Reddit + GitHub + HN are all reachable (200).
Verified end state (live)
- Port 3520 →
200, title "Hermes Newsroom · Command Center". - Mode
live, stories 71, sources ['github', 'hackernews', 'reddit']. - Providers: hermes-releases:ok(6), hermes-projects:ok(29), hermes-changes:ok(20), hermes-discussions:ok(3), reddit-search:ok(94).
- Sample: "Hermes Agent v0.22.0 — The Threshold Release" (github), live HN/Reddit hits.
Known / open items (not blocking)
- Bluesky 403 — off. To re-enable, fix egress/region or add a proxy; it's the only social source that fails here.
- Hermes gateway not connected — "My Hermes Daily" / personal feed stays empty until the local Hermes API gateway is started. Independent of Newsroom itself.
- No server log file. The
.cmdlaunchesnext startto a detached console (/min, no capture). Consider redirecting to a log for future triage.
Key lesson (generalized)
For any 127.0.0.1:PORT server behind a Hermes desktop plugin: test the port,
not the plugin. Blank frame = server down. A durable launch needs its own process
group (start "" /min in a Startup .cmd, or Popen(start_new_session=True, stdin/out/err=DEVNULL)). Always prove durability by re-probing the port in a
separate call, not just immediately.
Related
- 2026-10-10-trace-analysis-and-fix (different project, same "local service down" class)
Follow-up hardening (same session)
Hardened the autostart launcher so future failures are triage-able and idempotent:
- Event log — every launch appends a timestamped line to
C:\Users\fight\src\hermes-newsroom\logs\events.log(autostart triggered/started next start/already running - skip). This is the durable trail the incident lacked. - Idempotency guard — before spawning, checks
netstatfor a listener on :3520; if one exists it logs "already running - skip" and exits. No duplicate servers. - Server output —
next startstdout/stderr →logs\server.log(Next.js buffers the "Ready" line, so it's sparse, but captures crashes/errors). - Verified both branches: kill → launcher → 200 (start); re-run while up → skip, still exactly 1 listener (guard). Both survived the agent kernel (parent = cmd.exe).
Gateway fix (session 2 — "proceed with fixes")
Enabled the Hermes API Server so the Newsroom personal feed can reach the local gateway.
- Why it was disconnected: Newsroom's
src/newsroom/hermes/server.tsreads~/.hermes/gateway_state.json→platforms.api_server.listener_base+API_SERVER_KEYfrom the profile.env. Neither existed → "Hermes gateway is unavailable". - Fix:
- Appended to
C:\Users\fight\AppData\Local\hermes\.env:API_SERVER_ENABLED=true+ a generatedAPI_SERVER_KEY(48-hex). - Added
platforms.api_server(enabled:true, host:127.0.0.1, port:8642) toconfig.yaml(the.envtoggle alone didn't survive the gateway's direct-spawn re-ingest). hermes -p default gateway restart→[Api_Server] API server listening on http://127.0.0.1:8642,gateway_state.json.listener_basenow set.
- Appended to
- Verified end-to-end:
GET http://127.0.0.1:8642/health→200POST /v1/chat/completions(Bearer key) → returned text, real usage (16k prompt tokens)- Newsroom
GET /api/newsroom/hermes→{"connected":true,"message":"Hermes connected"}
- Note: the API server is per-profile-multiplexed (endpoints
/p/<profile>/v1under the shared listener); the base/v1+/healthwork for Newsroom. AScheduled Task: Hermes_Gatewayautostarts it, so it survives reboots.
Bluesky 403 — definitive (not fixable from this box)
public.api.bsky.approot → 200, but allapp.bsky.*API routes → 403 (Cloudflare bot-wall on this egress IP/region);www.bsky.appunreachable.- No egress proxy available (
hermes egressbinary missing, noHTTPS_PROXYset). - Decision: keep
socialSources.bluesky=false. Re-enabling requires a working outbound proxy or a different egress — out of scope here. GitHub/HN/Reddit cover the social/dev news; this is cosmetic.
Final state
- Newsroom: live, 75 stories (github + hackernews + reddit), personal feed now
reaches Hermes (
connected:true). - Autostart + event/idempotency logging in place; API server + Newsroom server both durable across reboots.