Skip to content

fix: guard _parse_cooldown against malformed repeat values; close file handle with context manager#76

Merged
lsdefine merged 1 commit intolsdefine:mainfrom
kuishou68:fix/issue-75-scheduler-errors
Apr 16, 2026
Merged

fix: guard _parse_cooldown against malformed repeat values; close file handle with context manager#76
lsdefine merged 1 commit intolsdefine:mainfrom
kuishou68:fix/issue-75-scheduler-errors

Conversation

@kuishou68
Copy link
Copy Markdown
Contributor

Description

Fixes two bugs in reflect/scheduler.py:

Fix 1 — Prevent ValueError/IndexError in _parse_cooldown

When a task JSON has a repeat value starting with "every_" but malformed (e.g. "every_", "every_h"), the code crashed with an unhandled exception. Added a try/except (ValueError, IndexError) guard around the parsing block so it falls through to the existing warning+fallback instead of crashing the scheduler.

Fix 2 — Use context manager to close file handle

Replaced bare open().read() on line 81 with a with block to guarantee the file handle is closed even on exception, preventing potential resource leaks.

Closes #75


Signed-off-by: Cocoon-Break 54054995+kuishou68@users.noreply.github.com

…e handle with context manager (Closes lsdefine#75)

Signed-off-by: Cocoon-Break <54054995+kuishou68@users.noreply.github.com>
@lsdefine lsdefine merged commit 315ce29 into lsdefine:main Apr 16, 2026
shaun0927 added a commit to shaun0927/GenericAgent that referenced this pull request Apr 17, 2026
After PR lsdefine#76 wrapped _parse_cooldown in try/except, parse('every_0h')
still returns timedelta(0). The cooldown check at check() then always
fires the task on the next 120s scheduler cycle, in effect running a
side-effectful task continuously instead of every N hours.

Add a positive-interval validation inside the existing try block so
the malformed case falls through to the existing 'fallback to 20h
cooldown' warning path, the same way 'every_h' or 'every_xyz' do.

Builds on the guard introduced by PR lsdefine#76.
shaun0927 added a commit to shaun0927/GenericAgent that referenced this pull request Apr 17, 2026
Closes lsdefine#96.

PR lsdefine#76 already converted the scheduler.py read site to a context
manager. Apply the same treatment to the remaining unmanaged
open() calls that this audit found across ga.py, agentmain.py,
and frontends/wechatapp.py.

Sites updated:

  ga.py
    - 23  : code_run header copy into the temp script
    - 387 : prepend-mode read of existing file in do_file_write
    - 388 : prepend-mode write of new+old back to disk
    - 424 : _check_plan_completion read of plan.md
  agentmain.py
    - 16  : tools_schema*.json load
    - 24  : global_mem.txt initial seed
    - 27-28: global_mem_insight.txt initial seed (was nested
            open(...).write(open(...).read()), so two leaks)
    - 33  : tmwebdriver cdp_bridge config.js seed
    - 105 : /session.<key> = <file> case (refactor 47f106c
            kept the unmanaged read)
    - 242 : reflect log append
  frontends/wechatapp.py
    - 183 : decrypted media bytes write to temp dir

These match the pattern in lsdefine#48 ("multiple calls then model
unresponsive, needs restart") for long-running adapters where
GC of unreferenced file objects is delayed and FD limits matter.
The launcher / startup-only sites are still affected because
the same handler is reused in reflect-loop code paths.

No behavior change: all reads/writes use the same modes,
encodings, and bytes; only the file handle release timing changes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: in scheduler.py raises ValueError/IndexError on malformed repeat values; open() file handle leak

2 participants