Skip to content

Factory reset leaves the old backend holding :4242/:4243 — the next setup fails Edge init #40

Description

@emooreatx

Factory reset restarts the app but leaves the old backend holding :4242/:4243, so the next setup cannot boot

Found by driving reset in CI for the first time (CIRISAgent#1150, five-platform gate run 34072801004, macOS and Linux desktop legs).

What happens

  1. Complete setup, reach Interact.
  2. Login footer → Reset device → confirm. factoryReset() runs: clears the signing key, deletes the .env, sets _resetSuccess, and the app restarts into the wizard. All of that works — logout and reset_device both pass, in ~1.6s and ~5.1s.
  3. Run setup again. The backend the app spawns exits 1 before serving:
Setting CIRIS_FORCE_FIRST_RUN=1
Server PID: 22351
Waiting for server to be ready...
[FAIL] backend failed: Server process exited unexpectedly (exit code: 1)

and the backend's own log says why:

ERROR - Edge runtime initialization failed (REQUIRED foundation dep):
        Edge transport ports are held by another process
        (ReticulumTransport::new: ...)
CRITICAL - Runtime initialization failed: Initialization sequence failed
ERROR - [EXIT] Fatal error in main (PID=22351)

The previous backend is still holding :4242 (Edge transport) and :4243 (node read API) when the new one starts.

Why we think it is the restart path, not the backend

The agent releases those ports on a graceful shutdown — that is CIRISAgent#1102, fixed in 2.10.0: CIRISRuntime.shutdown() now calls shutdown_node() then Edge.close() before exit. That release is bypassed when the process is killed rather than asked to stop, because the transport is Rust threads that outlive a kill -9.

So the question is what the app does to its backend across a factory reset. If it kills the process (or drops it and starts a second), the old transport keeps the ports and the next boot cannot bind. If it asks the backend to shut down and waits, the 2.10.0 release path runs and the ports come back.

We are not certain which of those the app does — that is your side, and we would rather ask than guess.

Why it matters beyond CI

This is not a harness-only sequence. Reset device → set up again is a normal user action, and on desktop it is the documented escape hatch from a broken install (the always-on link in the Login footer, #794 Bug C). If the ports are still held, the user's next setup fails with a message about Edge transport that tells them nothing they can act on.

We worked around it in the gate by polling until 4242/4243/8080 are free before the next setup, capped at 60s, failing loudly if they never are. That keeps CI honest; it does not help a user.

What would settle it

Either the app asks the backend to stop and waits for it (letting the 2.10.0 graceful release run), or it kills it and then waits for the ports before starting the next one. If you already do the former and the ports are still held, that is ours and we will reopen CIRISAgent#1102 with your evidence.

Agent-side references: CIRISAgent#1102 (transport outliving shutdown), CIRISAgent#1150 (the gate that found this).

🤖 Generated with Claude Code

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions