Hygiene: fix numpy-bool manifest crash + 3 Windows/frontend defects from Hamish validation#24
Merged
Merged
Conversation
…teardown)
_json_default only special-cased (np.floating, np.integer), so an np.bool_ —
which the A1 cymbal evidence was the first code to put into a manifest — fell
through to `raise TypeError("Not JSON-serializable")`, killing drum teardown at
write_json (hit live on Windows). Handle np.generic instead, which covers every
numpy scalar (bool_, floating, integer) across numpy 1.x and 2.x (2.0 renamed
np.bool_'s repr to numpy.bool). Ships the same change Mac hotfixed locally so his
clone reconciles on pull.
Regression: write_json serializes {np.bool_, np.float64, np.int64, ndarray, Path}
and reads it back.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Dn8XfTBWPfKA9poDbkYQU6
Two tests were environment-fragile and failed on a real Windows install:
- test_separate_uvr_maps_and_caches asserted the model dir `.endswith("models/uvr")`,
which fails on Windows backslashes — compare Path.parts[-2:] == ("models","uvr").
- test_analyze_records_fallback_chain relied on beat_this being absent; it's
installed on Windows, so no fallback happened. Monkeypatch _analyze_beat_this to
raise ImportError so the fallback chain is exercised regardless of the env.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Dn8XfTBWPfKA9poDbkYQU6
After a server restart the in-memory job store is empty, so /api/job/{id} returns
404 for an in-flight job id — but the poller ignored the status and looped
forever on the missing job. Check for 404 and surface "Job not found (the server
was restarted). Please re-run." A /favicon.ico route returns 204 to silence the
per-load 404 in the local server console.
Tests: the poller's 404 contract (test_unknown_job_is_404) and the favicon 204.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Dn8XfTBWPfKA9poDbkYQU6
MacFall7
marked this pull request as ready for review
July 10, 2026 04:05
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Defects found during first real-world validation on Hamish (Windows 11, full install,
main@b20a7f5). Two production crashes from the same numpy-scalar leak (at two different serialization boundaries), plus two environment-fragile tests and a frontend loop.The numpy-scalar leak (both boundaries)
Root cause:
np.polyfitreturnsnp.float64, so_analyze_beat_thisproduced annp.bool_tempo_assumed(np.float64 <= 0.0) that entered the manifest/job dict on the beat_this path (Hamish; a librosa-only env masks it). It bit at two boundaries:write_json(manifest) →TypeError: Not JSON-serializable→ drum teardown died.GET /api/job/{id}→ FastAPI/pydantic (nodefaulthook) →PydanticSerializationError: numpy.bool→ 500 → the SPA'sJSON.parsedied. (The SSE/api/progresspath survived viajson.dumps(default=str).)Fixed at three levels:
fix(io)—_json_defaulthandlesnp.generic(all numpy scalars, numpy 1.x/2.x) →write_jsonboundary. (Mac's original hotfix — shipped identically.)fix(analysis)— producer contract:_bpm_from_beats→float,tempo_assumed→bool,_bpm_candidates→float. Evidence is plain types at the source.fix(web)—job_statusround-trips through the numpy-aware encoder (json.dumps(default=_json_default)/json.loads) before returning →/api/jobboundary. (Matches Mac's uncommitted Hamish hotfix so his pull reconciles.)Verified the boundary fix is necessary: FastAPI's
jsonable_encoder(np.bool_)raisesValueError(the 500); the round-trip yields plain{"flag": true}.The other three defects
test:Windows path —test_..._uvr...assertedendswith("models/uvr")(fails on backslashes) → comparePath(...).parts[-2:] == ("models","uvr").test:isolation —test_analyze_records_fallback_chainassumedbeat_thisabsent; it's installed on Hamish → monkeypatch_analyze_beat_thisto raiseImportError.fix(web):poller — after a restart,/api/job/{id}404s a dead id and the poller looped forever → stop on 404, surface "Job not found (server restarted)". Added/favicon.ico→ 204 to kill console noise.Commits (conventional)
5e8eaacfix(io) ·00f5917test(portability) ·638be1dfix(web: poller+favicon) ·50ad4adfix(analysis: plain evidence) ·d68b718fix(web: /api/job boundary)Verification
pytest -q→ 199 passed, exit 0 (also green underFORCE_COLOR=1, matching CI).python -m benchmarks.run_benchmarks→ PASSED.write_json;np.bool_/np.float64/np.int64/ndarrayplanted in a job result →GET /api/job/{id}returns 200 valid JSON (was 500).Draft — not for merge without Mac's gate.
🤖 Generated with Claude Code
https://claude.ai/code/session_01Dn8XfTBWPfKA9poDbkYQU6