Skip to content

fix(cli-apps): lighten npm install + friendly timeout to avoid service restart#8

Merged
Ho1yShif merged 3 commits into
mainfrom
fix/cli-install-crashes-service
Jul 10, 2026
Merged

fix(cli-apps): lighten npm install + friendly timeout to avoid service restart#8
Ho1yShif merged 3 commits into
mainfrom
fix/cli-install-crashes-service

Conversation

@Ho1yShif

Copy link
Copy Markdown
Collaborator

Problem

Installing an npm-based CLI App (e.g. GET /api/settings/cli-apps/install?name=hyperframes) on a Starter instance made the whole nanobot web service return 502 Bad Gateway for ~15s, then restart and recover with a fresh WebSocket token.

Root cause (confirmed from Render metrics + logs — NOT OOM)

The earlier OOM hypothesis is disproven:

  • Memory peaked at ~300 MB against the 512 MB limit (baseline ~100 MB) — never hit the ceiling.
  • CPU peaked at 0.20 against the 0.5 limit — never maxed.
  • Timeline: 00:01:56 npm install starts → 00:02:27 requests hang (responseTimeMS=45065, responseBytes=0 = origin unreachable = the 502s) → 00:02:40 container fully restarts ([entrypoint] starting as uid=0(root) re-runs) → 00:02:49 healthy → 00:03:45 Render logs Instance restarted.

Mechanism: the runtime npm install -g starves the single 0.5-CPU instance enough that it stops answering Render's health check (healthCheckPath: /, which serves the ~223 KB WebUI SPA), so Render restarts the container. The install already runs in asyncio.to_thread, so it's resource contention — not an event-loop deadlock and not a hard OOM.

Changes

  • nanobot/apps/cli/service.py
    • _npm_argv: add --no-audit --no-fund --maxsockets 4 to install/update to flatten the CPU/network burst (npm-only; pip/uv/brew untouched).
    • _run_argv: convert subprocess.TimeoutExpired into a friendly CliAppError(status=503) advising an instance upgrade, instead of leaking a raw Python traceback to the WebUI.
  • README.md: note that Starter runs the core experience (chat, web search/fetch, memory) fine, but resource-intensive tasks (npm CLI Apps, image rendering) may briefly overwhelm the instance and can be run reliably by upgrading to a larger plan (Standard, 2 GB); cross-referenced from Cost expectations; fixed a pre-existing "dask" typo.
  • tests/cli_apps/test_service.py: new tests for the npm flags and the timeout→503 mapping; updated the stale-install test's argv expectation.

The blueprint plan/disk are intentionally left unchanged — Starter is a fine lean default, and instance upgrades stay documented rather than forced.

Verification

  • pytest tests/cli_apps/ → 37 passed; pytest tests/webui/ → 97 passed; ruff check nanobot/ → clean.
  • Post-merge (recommended): redeploy and re-trigger the install — on Starter, a slow/failed install now shows the friendly upgrade message; on an upgraded Standard instance, the install completes with no 502/restart (watch metrics + logs for absence of Instance ... restarted).

🤖 Generated with Claude Code

Ho1yShif and others added 3 commits July 9, 2026 19:51
…e restart

Installing an npm-based CLI App on a small Render instance could 502 the whole
service: the runtime `npm install -g` starves the 0.5-CPU box enough that it
stops answering the health check, so Render restarts the container. Confirmed
from metrics it is NOT an OOM (memory peaked ~300MB of 512MB, CPU 0.2 of 0.5)
— it is health-check-triggered restart under install-time resource contention.

- _npm_argv: add --no-audit --no-fund --maxsockets 4 to install/update to
  flatten the CPU/network burst (npm-only; pip/uv/brew unchanged).
- _run_argv: convert subprocess.TimeoutExpired into a friendly CliAppError(503)
  advising an instance upgrade instead of leaking a raw traceback.
- README: note that Starter runs the core experience fine but resource-intensive
  tasks (npm CLI Apps, image rendering) may need a Standard upgrade; fix typo.

Blueprint plan/disk intentionally unchanged (lean default + documented upgrade).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Match the codebase convention — error strings elsewhere in nanobot/apps use
plain ASCII, not em-dashes. Behavior unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Merge the instance-plan and persistent-disk upgrade guidance into a single
Note, covering both the ~15s restart and the "No space left on device" cases.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@Ho1yShif Ho1yShif merged commit fe525ed into main Jul 10, 2026
1 of 5 checks passed
@Ho1yShif Ho1yShif deleted the fix/cli-install-crashes-service branch July 10, 2026 03:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant