Skip to content

Annotate feedback can be lost when submit auto-closes localhost session after CLI timeout on Windows/Codex #678

Closed

Description

@0okay

Summary

While using plannotator annotate <file.md> from Codex on Windows, a user submitted annotation feedback in the browser. The Plannotator localhost page auto-closed within a few seconds after submission. The original CLI invocation had already timed out in the agent environment, and the submitted feedback was not recoverable from session files, draft/history files, active sessions, or browser storage.

This makes it possible for a user to spend time reviewing a file, click submit successfully, see the page close, and still lose all feedback.

Environment

  • OS: Windows 11 Pro 64-bit, build 22621
  • Shell: PowerShell
  • Browser: Microsoft Edge
  • CLI binary: C:\Users\Administrator\AppData\Local\plannotator\plannotator.exe
  • Binary timestamp: 2026-05-07 15:43:56 local time
  • CLI wrapper reports Bun file version/product version 1.3.11
  • GitHub latest release at the time of report: v0.19.10
  • Context: Codex/agent shell command with a timeout around a long-running plannotator annotate process
  • File being annotated: local Markdown file on a Windows path containing spaces and non-ASCII characters

What Happened

  1. Ran plannotator annotate "<absolute Windows path to file>.md" from Codex.
  2. The tool/browser session opened on a localhost port.
  3. The Codex-side shell command timed out before the user finished reviewing.
  4. The user continued reviewing in the browser and clicked submit.
  5. The page auto-closed about 3 seconds after submission.
  6. The browser tab then showed ERR_CONNECTION_REFUSED for http://localhost:56952/.
  7. The submitted annotations were not applied to the Markdown file and could not be recovered.

Expected Behavior

At least one of the following should happen:

  • Submitted feedback is durably written before the browser page is closed.
  • If the agent/CLI caller has timed out or disconnected, the web UI should warn the user and preserve feedback locally/server-side.
  • Feedback should be recoverable through ~/.plannotator session/draft/history files or a plannotator sessions/recovery command.
  • The submit flow should not close the page until persistence and delivery to the agent are confirmed.

Actual Behavior

  • The browser page closed/left the user on a dead localhost page.
  • The Markdown file was unchanged.
  • No recoverable annotation content was found.
  • plannotator sessions did not list the dead 56952 session afterward.

Diagnostics Performed

Evidence from the local machine:

  • Edge history contained http://localhost:56952/, confirming the user-submitted session existed.
  • The page shown after submit was ERR_CONNECTION_REFUSED for localhost:56952.
  • Active Plannotator sessions after the incident only showed other ports, not 56952:
    • http://localhost:49917
    • http://localhost:61135
    • http://localhost:51033
  • Current Plannotator processes only corresponded to those other active sessions.
  • ~/.plannotator/sessions contained JSON files for the other sessions but not the submitted 56952 session.
  • ~/.plannotator/drafts was empty.
  • Searching ~/.plannotator for the dead port, the annotated file name, and annotation-related terms did not find the submitted feedback.
  • Browser storage/LevelDB searches did not reveal the submitted annotation content.
  • The target Markdown file had the same hash and last-write timestamp as before submission.

Related/Maybe Relevant Issues

This may be related to recovery/session persistence and port lifecycle issues, but the user-visible failure mode here is specifically: submit succeeds from the user's point of view, the page closes, and feedback is lost if the CLI/agent side has timed out.

Potentially related:

Suggested Fix Direction

  • Persist submitted annotations before attempting to send them to an agent/hook/CLI stdout.
  • Add an explicit durable recovery artifact for every submitted annotate session.
  • If the caller has disconnected/timed out, keep the page open and show a "feedback saved locally but could not be delivered" state with a copy/download/retry option.
  • Include the session port or session id in persisted files so dead localhost sessions can be matched after the fact.

Activity

  1. 0okay commented on May 7, 2026

    @0okay
    Author

    Additional source-code finding after checking main (71492ec, v0.19.10): this is not a complete absence of persistence. There is draft persistence, but the submit path appears to delete the draft before handing feedback only to the waiting decision promise.

    Relevant code paths:

    • packages/shared/draft.ts: drafts are saved under ~/.plannotator/drafts/<contentHash>.json.
    • packages/ui/hooks/useAnnotationDraft.ts: annotation changes auto-save to /api/draft when in API mode and not submitted.
    • packages/server/annotate.ts: /api/draft routes to handleDraftSave/Load/Delete.
    • packages/server/annotate.ts: /api/feedback does:
      1. deleteDraft(draftKey)
      2. resolveDecision({ feedback, annotations })
      3. returns { ok: true }

    Unlike plan review (packages/server/index.ts) or Pi plan flow (apps/pi-extension/server/serverPlan.ts), the generic annotate server's feedback handler does not call saveAnnotations or saveFinalSnapshot before deleting the draft. So if the CLI/agent caller already timed out or no longer receives the decision, the previously auto-saved draft is removed and there is no final .annotations.md/snapshot recovery artifact.

    That matches the observed user failure: the user clicked submit, the UI considered feedback sent and auto-closed, but the CLI result was not captured and the draft had already disappeared.

  2. 0okay commented on May 27, 2026

    @0okay
    Author

    Additional reproduction on Windows/Codex with plannotator 0.19.23.

    Scenario:

    • OS/shell: Windows 11 + PowerShell 7.6.1
    • Plannotator: C:\Users\Administrator\AppData\Local\plannotator\plannotator.exe, plannotator --version => plannotator 0.19.23
    • Command shape: plannotator annotate "<absolute Windows folder path>"
    • Mode from /api/plan: annotate-folder
    • Target: a local folder containing multiple Markdown patent-drafting files; path contains spaces, Chinese characters, and parentheses.

    What happened:

    1. The annotate command was launched from the Codex shell with a long timeout.
    2. The browser opened correctly on http://localhost:61803.
    3. /api/plan showed the correct target folder path, not annotate-last.
    4. The Codex shell command timed out after about 10 minutes while the user was still reviewing.
    5. The user later submitted annotations from the browser UI.
    6. After submission, the Plannotator process/session disappeared.
    7. The annotation payload was not available to Codex and could not be recovered.

    Recovery checks performed after the lost submission:

    • ~/.plannotator/sessions no longer contained the 61803 session; the previous session JSON was gone.
    • No active plannotator process remained for that session.
    • Search under ~/.plannotator for the target folder name, localhost:61803, 61803, annotation, feedback, and Chinese annotation keywords did not find the submitted feedback.
    • Existing draft file under ~/.plannotator/drafts was old/unrelated.
    • Search in Edge local storage / LevelDB / History for localhost:61803, 61803, annotation/feedback terms did not reveal recoverable annotation content.

    User-facing impact:

    The user spent time annotating several Markdown files, clicked submit, and the feedback was lost because the waiting CLI side had already timed out. This still reproduces on 0.19.23 and with annotate-folder, not only single-file annotate.

    Workaround being used locally:

    Run plannotator annotate <path> in a separate long-lived PowerShell/Windows Terminal process and keep that process alive until after submit. Running it inside an agent shell command with a timeout is unsafe because the submit path appears to depend on the original waiting process receiving the final payload.

    Suggested behavior remains the same: submitted annotations should be durably written before draft deletion / session teardown, and the UI should not silently close if the CLI/agent receiver is no longer connected.

  3. backnotprop commented on Aug 9, 2026

    @backnotprop
    Owner

    Thanks for the detailed report, and for the patience here. This is confirmed and fixed by #1237, just merged.

    What ships: the server now writes the submitted feedback to a durable record under your data directory before it deletes the auto-saved draft, so a CLI-side timeout can no longer leave the feedback existing nowhere. If the record cannot be written, the draft is kept as the recovery copy instead. Sessions with annotate history disabled keep their fully stateless behavior.

    This will be in the next release. Thanks again @0okay.

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

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions