Skip to content

Fix 9 problems from the log (http, db, perf) - #149

Merged
danielehrhardt merged 4 commits into
mainfrom
godmode/43-fix-9-problems-from-the-log-http-db-perf
Oct 11, 2026
Merged

danielehrhardt merged 4 commits into
mainfrom
godmode/43-fix-9-problems-from-the-log-http-db-perf

Conversation

@danielehrhardt

Copy link
Copy Markdown
Contributor

Fix 9 problems from the log (http, db, perf)

Five of the reported problems had causes in the code and are fixed; two are left unchanged on purpose. Typecheck passes and the core suite passes on the branch merged with the latest main, apart from tests that fail only inside this session's environment.

Fixed

  • GET /api/android/devices/:id/screenshot failed: a screenshot cut short while the phone went away threw a raw zlib error and answered 500. It is now a device error the app can show ("The phone sent an incomplete picture").
  • could not close run … / closed 1 paused run(s) that couldn't be continued: on every start, the local copy of a paused run in a runner's chat was taken for a lost pause and cancelled, which fails while the runner is offline. Its pause is kept on the runner, so these copies are now left alone.
  • Watchdog stopped a run after "Schedule wakeup": the run had already delivered its result and was waiting for the wakeup it had scheduled (about 21 minutes away) when the 20-minute stall limit failed it. The watchdog now allows the requested delay on top of the stall limit, also while a background task runs.
  • run failed: Claude Code exited with code 1 (3 times): all three hit the usage limit. Claude Code's own session transcript, checked for one of them, has the limit message, but it never reached Godmode. A run that ends with a non-zero exit and no output within 5 minutes of another run hitting the limit now waits for the reset. Delegated runs fail with "Claude's session limit is reached" instead.
  • slow database query: UPDATE messages SET blocks and most event loop blocked: a working run's message was rewritten whole every few seconds, and 7 to 9 MB of it were screenshots that never change.
    • Screenshots are now written once to a new table message_images (migration 87). When the run ends or pauses, the message is saved whole again.
    • Every reader gets the screenshots back, including the phone app's message page and picture endpoint, and recovery after a crash.
    • On a copy of the real database, repeat saves of such messages went from 6.5 ms median / 70 ms worst to 0.9 ms / 3.4 ms. That copy is much faster than the live database, so compare the ratio, not the absolute times.

Not changed

  • run failed: You've hit your session limit (2 times): the account's usage limit. Both were delegated runs, which fail by design and report to the run that delegated them.
  • slow database query: SELECT * FROM messages WHERE conversation_id = ? and the remaining blocked event loop: opening a chat in the desktop app loads the whole chat with every screenshot inline. The largest chats are 60 to 130 MB, and 71 messages from before the 8 MB screenshot cap hold 1.2 GB.
    • A real fix means the desktop app loads pictures on demand, as the phone app does since expo app improvments #147. That is a feature-sized change and belongs in its own ticket.
    • Trimming the old messages would delete stored screenshots, so I did not do it without an explicit decision.
  • The other one-off slow queries (100 to 400 ms on trivial statements) look like side effects of the same stalls rather than problems of their own; I did not trace them individually.

Tests

  • New or extended tests cover each fix: android, pause, heartbeats (watchdog), run-stream and runner.
  • Whole core suite on the merged branch: 1779 pass, 1 fail. The failure is folders.test.ts "list subfolders", which fails here because the temp directory has more than 500 entries; it passes with an empty temp directory.
  • An independent review of the diff found that main had moved on (a taken migration number and two new message readers), plus three smaller findings (a save for a deleted chat, non-atomic whole saves, a watchdog gap). All are fixed in the last commit.

For Daniel

  • Decide whether the desktop app should load chat pictures on demand (new ticket), and whether old messages above the 8 MB cap may be trimmed.

Task #43 · done by Self-Healer with Godmode Bot

… runs and silent usage limit exits

- A screenshot that arrives cut short (the phone went away meanwhile) is a device error the app can show, not a failed request.
- The copy of a run that stands still on a runner is no longer closed, and warned about, on every start.
- The watchdog lets a run sleep as long as it asked Claude Code to wake it later (ScheduleWakeup).
- A run Claude Code ends without a word right after the usage limit ended another one waits for the reset too.
…ry save

While a run works its message is saved every few seconds. Its screenshots are most of its size (up to 8 MB) and never
change: they are written once to message_images, the blocks are saved without them, and whoever reads the message gets
them back. When the run ends or stands still the message is saved whole again.
…lems-from-the-log-http-db-perf

# Conflicts:
#	packages/core/src/db/migrations.ts
…save, a sleeping run with a background task

- The message page and the picture of a step (phone app) read the screenshots a working run keeps apart.
- Saving a message whole and dropping what was kept apart is one transaction; a save for a deleted chat does nothing.
- A scheduled wakeup also counts while a background task runs.
@danielehrhardt
danielehrhardt merged commit 4f77194 into main Oct 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant