fix: three silent fallbacks from tonight now say what they did

Unreadable modality tags widened the erase to every position including
an image span; a partly-failed erase left some scenes changed; an
unreadable sigma disabled sharpening while still reporting it active.
A malformed reference slot claimed nothing was marked.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
digital-garbage
2026-08-23 04:50:23 +03:00
co-authored by Claude Opus 5
parent f426b260b5
commit ce9e679f0e
4 changed files with 36 additions and 7 deletions
+9 -1
View File
@@ -628,7 +628,15 @@ def build(object_info: dict, models_config: dict, params: dict, media: dict | No
n = int(num)
except ValueError:
n = 0
ref = _reference_by_slot(kind, n) if n > 0 else None
if n <= 0:
# A malformed slot is not "no reference marked" — reporting it as that
# sends the user to the Media Bin to fix a value that is wrong in the
# node. Say which it is.
report["unsatisfied"].append(
f"{s.get('node_class')}.{ci_name}: input source '{source}' is not a "
f"reference slot (expected e.g. 'ref#image:1').")
continue
ref = _reference_by_slot(kind, n)
if ref is None:
# Nothing marked in that slot. The socket is simply left unconnected —
# an unused reference slot is a normal state, not a setup mistake, so it
+5 -2
View File
@@ -881,11 +881,14 @@ def test_an_empty_slot_is_not_quietly_filled_with_something_else():
assert not isinstance(graph["slot_r"]["inputs"].get("ref_images.ref_image0"), list)
def test_a_malformed_slot_reference_does_not_crash_the_build():
def test_a_malformed_slot_says_it_is_malformed_not_that_nothing_is_marked():
""""No reference marked" sends the user to the Media Bin to fix a value that is wrong in
the node. The two are different problems and must not read the same."""
_graph, report = builder.build(
REF_OI, _slot_models(**{"ref_images.ref_image0": "ref#image:nope"}),
_ref_params(_img("m1", "a.png")))
assert not _ref_problems(report)
assert any("not a reference slot" in u for u in report["unsatisfied"])
assert not any("none marked" in w for w in report["wired"])
def test_the_loader_matches_what_the_destination_socket_asks_for():
+16 -3
View File
@@ -50,7 +50,13 @@ def _text_positions(meta, length):
return None # tags and conditioning disagree — touch nothing selectively
idx = (flat == 1).nonzero(as_tuple=False).reshape(-1)
return idx if int(idx.numel()) else None
except Exception:
except Exception as exc: # noqa: BLE001
# NOT silent: returning None here widens the operation from "text positions only" to
# "every position", which on H3 means erasing a text direction out of the reference
# image's conditioning. A caller that cannot see this happen cannot explain the
# result it gets.
print(f"[FunPack] negative_erase: could not read the modality tags ({exc}) — the "
f"erase applies to EVERY position, including any image span")
return None
@@ -154,7 +160,7 @@ def apply(positive, negative, strength, mode="project", renorm=True):
if unit is None:
return positive, "negative_erase: the negative conditioning has no usable direction"
out, touched = [], 0
out, touched, failed = [], 0, []
for entry in positive:
try:
tensor, meta = entry[0], (entry[1] if len(entry) > 1 else {})
@@ -162,8 +168,15 @@ def apply(positive, negative, strength, mode="project", renorm=True):
if new is not tensor:
touched += 1
out.append((new, meta) + tuple(entry[2:]))
except Exception: # noqa: BLE001
except Exception as exc: # noqa: BLE001
failed.append(str(exc))
out.append(entry)
if failed:
return positive, (f"negative_erase: {len(failed)} conditioning entr"
f"{'y' if len(failed) == 1 else 'ies'} could not be modified "
f"({failed[0]}) — NOTHING was changed, because a prompt where only "
f"some scenes had the negative removed is worse than one where none "
f"did")
if not touched:
return positive, "negative_erase: no conditioning entry could be modified"
return out, (f"negative_erase: {mode} {float(strength):.2f} on {touched} "
+6 -1
View File
@@ -1379,7 +1379,12 @@ class _SharpenDenoiser:
denoised = self._inner(x, sigma, **kwargs)
try:
s = float(sigma.flatten()[0]) if hasattr(sigma, "flatten") else float(sigma)
except Exception: # noqa: BLE001
except Exception as _e: # noqa: BLE001
# Once, not per evaluation — but never nothing. Silently returning here would
# leave quality_sharpness switched on, reported as active, and doing nothing for
# the whole run.
_log.failed("FunPackStudio", "quality sharpness (unreadable sigma)", _e,
"this sampler's steps are NOT being sharpened")
return denoised
if s > self._thr:
# Outside the window: nothing to sharpen, but the prediction is still KEPT. The