From 7e4246401683aa9368b3b3142db61521817978ae Mon Sep 17 00:00:00 2001 From: Brandon Walter <51866976+echoparkbaby@users.noreply.github.com> Date: Wed, 13 May 2026 10:31:35 -0700 Subject: [PATCH] fix: missing nonlocal on _drain's tracker vars (1.0.0-59) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After the chunk-read refactor, the inner _drain coroutine assigns to last_db_write_ts and last_pct_sample. Without nonlocal, Python compiles these as locals of _drain, so any READ before the first assignment raises UnboundLocalError. In 1.0.0-55 / -57 the bug was hidden by gather(return_exceptions= True), which silently swallowed the exception — the drain coroutine ended immediately, the asyncssh channel buffer filled up, and the remote badblocks blocked on pipe_write. THAT was the actual cause of the "parser silently never works" symptom, not anything to do with the chunk-read or tr-pipe logic itself. 1.0.0-57 dropped the gather (single drain after merging 2>&1), which made the next deploy surface the bug as an explicit error_text on the surface_validate stage: "cannot access local variable 'last_db_write_ts' where it is not associated with a value". Fix: add both vars to the nonlocal declaration. pending_log_chunks only gets .append/.clear (no reassignment) so it doesn't need nonlocal. This is the bug that's been hiding behind all the recent parser work. Sorry for the round trips. --- app/burnin/stages.py | 2 +- app/config.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/burnin/stages.py b/app/burnin/stages.py index c657368..5fa32ca 100644 --- a/app/burnin/stages.py +++ b/app/burnin/stages.py @@ -556,7 +556,7 @@ async def _stage_surface_validate_ssh(job_id: int, devname: str, drive_id: int) _push_update() async def _drain(stream, is_stderr: bool): - nonlocal bad_blocks_total, pid_seen + nonlocal bad_blocks_total, pid_seen, last_db_write_ts, last_pct_sample # Line-based drain. The wrapped badblocks command # pipes through `tr '\b' '\n'` at the shell level # so every progress update is a real newline- diff --git a/app/config.py b/app/config.py index 351ee4a..51d8766 100644 --- a/app/config.py +++ b/app/config.py @@ -86,7 +86,7 @@ class Settings(BaseSettings): ssh_key: str = "" # PEM private key content (paste full key including headers) # Application version — used by the /api/v1/updates/check endpoint - app_version: str = "1.0.0-58" + app_version: str = "1.0.0-59" # ---- Authentication (1.0.0-22) ---- # session_secret: HMAC key for signing session cookies. Empty = generate