Repository navigation
Description
Summary
A file named re.py sits in the shared OpenCode temp folder ~/.local/share/opencode/tmp/opencode/. Python puts the working directory (for python -c and -m) and the script's own directory on sys.path, so any Python process started from that folder imports this file as the standard re module and fails at startup.
Reproduction
Observed on macOS with nix Python 3.14.7 (/nix/store/...-python3-3.14.7):
cd ~/.local/share/opencode/tmp/opencode
python3 -c "import json"
Result (abridged):
File ".../opencode/re.py", line 25, in <module>
import logging
...
AttributeError: module 're' has no attribute 'escape' (consider renaming '.../opencode/re.py' since it has the same name as the standard library module named 're' and prevents importing that standard library module)
uv run with a script inside that folder fails the same way, because the script's directory is put first on sys.path.
The file
- Path: ~/.local/share/opencode/tmp/opencode/re.py, 8,357 bytes, modified 2026-10-18 02:04.
- Contents: an Alembic helper module from the operations-portal repository (its docstring describes helpers for Alembic revisions). It is not an OpenCode file. How it got into the shared temp folder is unknown.
Impact
One command in an affected session failed before it ran. The error looked like a broken Python install until the traceback named the file.
Workaround
python3 -I (isolated mode) keeps the working directory and the script directory off sys.path. Running from another directory also works. The file was left in place because it is not ours to delete.
Requests
- Find what writes module-named files (re.py, or any other standard library module name) into the shared tmp root, and stop it.
- Keep the shared tmp root free of Python modules. A per-session or per-tool subdirectory is enough.
- Document python3 -I for tools that run Python from the tmp folder.
Environment
- macOS (darwin), uv, nix Python 3.14.7
- OpenCode tmp folder: ~/.local/share/opencode/tmp/opencode (pre-created, approved for external access)
Acceptance criteria
- The writer of stdlib-named files (
re.py) into the shared tmp root is identified and stopped, or proven external and a guard/cleanup is in place. - The shared tmp root contains no Python modules named after standard-library modules.
- Verification:
python3 -c "import json"run from inside the tmp root succeeds.
Activity
dezren39 commentedon Oct 24, 2026
Triage update (issue-sweep-rotating, 2026-10-24, on main bca2f2e):
Investigated request 1 (find what writes module-named files into the shared tmp root):
git grepover the repo finds no code that writesre.pyor any Python module into the tmp root. The only tmp writers in core are specifically named temp files (e.g.persistent-pty/binary.bun.tswritesopencode-pty.<pid>.<uuid>.tmp;plugin/vcs/git.tsusesos.tmpdir()/opencode-untracked-<uuid>).packages/core/src/instructions/builtins.tstells the model "Prefer ${global.tmp} over generic system temporary directories... it is pre-created and approved for external access",packages/core/src/filesystem.ts(write path) notes clients stage files in "the server tmp directory, which the model is already told to prefer and permitted to access", andpackages/core/src/shell.tspoints child TMPDIR/TMP/TEMP at the same directory when OPENCODE_TMPDIR is set.So there is no in-repo bug to fix for request 1. The remaining requests are a product decision: moving to per-session/per-tool subdirectories (request 2) would change the documented shared-tmp contract above, and request 3 (document
python3 -I) only matters for tools run from that directory. Keeping this OPEN for that decision rather than closing it as not-a-bug, so the trade-off is recorded here.dezren39 commentedon Oct 26, 2026
🤖 Intake review — fleet monitor, 2026-10-26 run
Still live: no related issue or fix found this run; the file described in the body is an Alembic helper from the operations-portal repo — not an OpenCode file — so the writer is likely tooling that copies/syncs a working tree into the shared tmp root.
Related: none filed; the workaround (
python3 -I, or running from another directory) is recorded in the body.Notes / risks: impact so far is one failed command and a misleading traceback, hence priority/low; the risk is recurrence with a worse module name (
os.py,json.py).Suggested approach: grep session/tooling code paths that write into the tmp root, check mcpx/session scratch handling, and consider a startup sweep that warns on stdlib-named
.pyfiles in the tmp root.dezren39 commentedon Oct 28, 2026
Triage verdict: exposure confirmed, writer external — guard routed (queue task 2071)
Re-verified on current main
b0633cc697760085022fb5656ed92fac9ce49b9c(2026-10-28), updating the 2026-10-24 triage (mainbca2f2ecb7), whose no-in-repo-writer conclusion still holds:packages/core/src/instructions/builtins.ts:43still directs the model: prefer${global.tmp}over system temp directories, pre-created and approved.packages/core/src/shell.ts:273exports that root asTMPDIR/TMP/TEMPto shell commands whenOPENCODE_TMPDIRis set. The only other core reference (messaging/vars.ts:218) just returns the path..pyfiles — or arbitrary-named files — into the tmp root, and no stdlib-collision guard exists (git grep stdlibinpackages/core/src: no relevant hits). There.pyin the report is an operations-portal Alembic helper (per the issue body), i.e. external tooling/agent scratch, exactly as the 2026-10-24 triage concluded.Routing: follow-up small_fix enqueued as queue task 2611 — a warn-only sweep at tmp-root initialization/session start: top-level
*.pyfiles whose stem collides with a Python stdlib module name produce a log warning naming the file, the shadowing risk, and thepython3 -Iworkaround; files are never deleted or moved (they may belong to another project). It also adds thepython3 -Ihint to the builtins tmp guidance (request 3). Tests pin detection (stdlib hit warns, non-stdlib/non-.py/empty root quiet).8 remaining items
dezren39 commentedon Oct 28, 2026
🤖 Agent note · fix implemented, PR open, parked on CI
fix(core): warn on stdlib-named .py files in the shared tmp root (#132), branchqueue/2611-132-stdlib-warnat baseb0633cc697.packages/core/src/tmp-guard.ts— top-level-only scan of the shared tmp root for.pyfiles whose stem is a Python stdlib module name (CPython 3.14 list);Effect.logWarningnaming the file(s), the directory, the shadowing risk, and thepython3 -Iworkaround, once per process per collision set; files are never deleted, moved, or modified. Hooked intoInstructionBuiltIns.load()at session start. The builtins tmp guidance now also carries thepython3 -Ihint (issue request 3), with the pinned expectation inbuiltins.test.tsupdated.bun test ./test/tmp-guard.test.ts ./test/instructions/builtins.test.tsfrompackages/core— 9 pass / 0 fail;bun typecheckfrompackages/core— clean; oxlint on the 4 changed files — 0 warnings / 0 errors. One test caught a real bug during development (Effect.syncdoes not catch thereaddirSyncthrow on a missing root;warnnow usesEffect.try).dezren39 commentedon Oct 28, 2026
Done: implemented, tested, and opened PR #751 (targets main, not merged).
What changed (all in packages/core):
Test results (packages/core, this machine):
PR: #751
dezren39 commentedon Oct 28, 2026
Implemented and opened PR #751 (not merging, per task scope).
What changed (all in
packages/core):packages/core/src/tmp-stdlib.ts: top-level-only (never recursive) scan of the tmp root against the stdlib module list (194 names fromsys.stdlib_module_names);Effect.logWarningnames the offending file(s) and points at thepython3 -Iworkaround; warn-once per tmp root per process; never deletes, moves, or edits files; quiet on clean/missing/unreadable roots.Session.createrunsTmpStdlib.checkOnce(global.tmp)first (first session use);Global.nodeadded to the Session node deps (service resolved in the layer constructor so thecreateinterface is unchanged).python3 -Iwhen running Python with the tmp root as cwd.packages/core/test/tmp-stdlib.test.ts: stdlib-name hit, non-stdlib.pyignored, non-.pyignored, top-level-only scan, empty-root quiet, warn names file + workaround, warn-once, clean-root quiet, and files left untouched. Updated the builtins expectation for the new guidance text.Test results (packages/core on this machine):
bun typecheck(tsgo -b tsconfig.json tsconfig.tests.json): clean.bun test test/tmp-stdlib.test.ts test/instructions/builtins.test.ts: 15 pass, 0 fail.bun test test/session-create.test.ts test/shell-tmpdir.test.ts: 43 pass, 2 fail — both are 5s-timeout flakes in shell-spawning live tests; I stashed my changes and re-ran on the clean base tree, where the same tests flake, so this is environmental and unrelated.PR: #751 (targets
main, fixes #132, ready for review, not merged).dezren39 commentedon Oct 28, 2026
Dedupe note (operator, 2026-10-28): two PRs were opened for this issue — lane PR #748 and session PR #751 — from the dispatcher/lane binding gap. Verified overlapping implementations (shared surface: instructions/builtins.ts + test). Closed #751 as the duplicate; PR #748 is canonical (queue-bound lane PR).
Merge pull request #748 from developing-today/queue/2611-132-stdlib-warn
dezren39 commentedon Oct 28, 2026
agent-note:v1 — task 2611 (repo-health-opencode-pilot, lane A, agent repo-queue-worker-shift-opencode)
The guard branch is landed: PR #748 merged this shift (merge commit ec310fc). PR #751 was the parallel duplicate and stays closed per the operator dedupe note; #748 is canonical.
Verification before merging: on the laptop at the PR head (5fc0d9c),
bun test test/tmp-guard.test.ts test/instructions/builtins.test.ts— 9 pass / 0 fail. CI: typecheck, nix-eval, build (linux/windows) and affected-packages green;unit (linux)/unit (windows)fail only on the two standing TUI input-scope permission tests (log-checked — the same failure on merged PRs #745/#741/#740); the test workflow's e2e jobs were still queued in the runner backlog at merge time.All five packet acceptance criteria are met by the merged change (warn-only top-level sweep at session start via InstructionBuiltIns.load, files never touched, quiet on clean roots, python3 -I in the builtins tmp guidance, tests pinning detection). This issue stays open for the two reporter-machine items no repo change can settle: the stray external
re.pystill sitting in that machine's tmp root (acceptance: tmp root contains no stdlib-named modules) and thepython3 -c "import json"verification run from inside that folder.