Skip to content

(Claude) Known limit: on Windows a live-update rewrite can fail while the server is sending that page #396

Open

Description

@cboos

Known limit, not an observed failure. This records a Windows edge case in live updates and the message to watch for, so that a report showing it can be recognised.

The limit

Live updates rewrite a page with atomic_write_text: a temp file, then os.replace (claude_code_log/utils.py). On Windows, os.replace fails with PermissionError while another process holds the target open without FILE_SHARE_DELETE.

Since #352, the live server opens a page with a retry and holds that handle while it serves the page (_pin_file, claude_code_log/server.py:194). So for the length of one transfer, the writer cannot replace that file.

The writer retries too (_replace_with_retry), but only for _SHARING_RETRY_ATTEMPTS = 10 tries with a 20 ms pause, about 180 ms in all. A transfer that takes longer, for example a large session page sent to a slow client, outlasts the retry. The rewrite then fails for that tick, and the page is rewritten on the next one.

#352 listed this as a known limit, and its follow-up comment worked out the mechanism. Nothing has shown it happening so far. The two CI flakes first suspected of it (on #353 and on main at 093f452) were a test bug instead (PR #394).

Tripwire

If it happens, the watch loop reports a failed conversion whose exception is a PermissionError on an .html page:

  • serve --watch: watch: conversion failed: PermissionError(13, ...) (claude_code_log/cli.py:2356)
  • watch: conversion failed: PermissionError(13, ...) (claude_code_log/cli.py:2695)

In CI the same message would appear in a live-update browser test's output on a Windows cell.

If you see that message on Windows, this issue is the likely cause. Please comment with the page's size and what was reading it.

Candidate fixes, if it ever shows

  • (a) Give the writer's retry a time budget, about 2 s, instead of a fixed count.
  • (b) Have the server send a snapshot read into memory, so it holds no handle during the transfer. This costs memory for a large page.

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

    documentationImprovements or additions to documentation

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions