Skip to content

0.12.0 on Windows: every review fails with PermissionError under C:\Program Files #232

Description

@huhamhire

Affects the released 0.12.0 Windows build. Any /describe or /review fails, so the installed app is effectively unusable.

PermissionError: [Errno 13] Permission denied:
'C:\Program Files\Code Meeseeks\resources\pragent\python\Lib\site-packages\litellm\
 litellm_core_utils\tokenizers\fb374d419588a4632f3f557e76b4b70aebbca790.<uuid>.tmp'

The traceback goes PRDescription.__init__ → TokenHandler → tiktoken.get_encoding("o200k_base") → read_file_cached → open(tmp, "wb").

Cause

Not a permissions setting — a bad file inside the package.

litellm points TIKTOKEN_CACHE_DIR at its own litellm_core_utils/tokenizers/ and ships encoding files there so tiktoken works offline. But the files it ships fail the expected_hash pinned by the tiktoken it depends on. Measured against litellm 1.99.0 / tiktoken 0.12.0:

encoding shipped by litellm matches tiktoken''s pin
o200k_base yes no
cl100k_base yes no
p50k_base yes no
r50k_base no —

tiktoken therefore treats the cache as invalid on every run: it deletes the file and re-downloads it into site-packages. Writable while building, read-only once installed under C:\Program Files — hence the crash.

Not model specific. The reported trace is a CLI provider (model='codex' → o200k_base), but a gpt model resolves through encoding_for_model() to the same stale files. Every path that counts tokens hits this.

Why it shipped

  • A dev machine never shows it. vendor/ is writable there, so tiktoken repairs itself on the first run and everything looks permanently fine.
  • CI never showed it either. The build machine can also write, so the runtime assembled and smoke-tested clean — the stale file loads wherever it can be re-downloaded. "CI passed" proved nothing about the installed copy.

Same class as the pre-written .secrets.toml (already handled in the assembler): a dependency that writes under its own package at runtime. That one was fixed as a one-off without becoming a rule, which is why this recurred.

Fix

scripts/tiktoken-cache.py:

  • prime (assemble time, before slimming) — repairs the bundled bytes so the cache is a hit and nothing is written at runtime;
  • verify (smoke test, after slimming) — compares bundled bytes against tiktoken''s pinned hashes, so this cannot ship broken again; running after slimming also catches a slim rule that deletes the cache.

The assertion compares hashes rather than just loading an encoding, since loading is exactly what fails to discriminate here. Expected hashes are read from the installed tiktoken, never copied into our source, so they cannot drift on the next upgrade.

Verified end to end: restoring litellm''s stale copy makes verify fail; after prime, both encodings load from a genuinely read-only directory (write denied via icacls); putting the stale file back into that same read-only directory reproduces the reported PermissionError exactly.

The general rule is now recorded in AGENTS.md and docs/arch/02-agent/05-pragent-runtime.md.

Fix release

Ships in 0.12.1.

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

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions