Pipe slot 0 is populated and RMStylesPipeOut unpacks it correctly; all eight return paths emit an 8-tuple with positive at index 0. The content policy is rewriting the text in place instead: across 293 styles, 26% clean / 70% sanitized / 4% blocked. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012uM7Ru1JYn48n6c5Rzwd99
7.3 KiB
BUGS
Open
RM Styles Pipe: positive prompt missing from its slot in the pipe
Reported: 2026-08-24 Nodes: RM Styles Pipe, RM Styles Pipe Out Status: Investigated — the pipe position is correct. The positive is being rewritten in place by the content policy, not misplaced or dropped. Awaiting confirmation that this is what was actually observed.
Symptom (as reported): the styles pipe "no longer seems to be outputting the positive prompt where it's supposed to be in the pipe."
Known layout — RM_STYLES_PIPE index 0 is Positive:
0 Positive · 1 Negative · 2 Motion · 3 ImageLoras · 4 MotionHigh · 5 MotionLow · 6 Number · 7 Name · 8 PolicyStatus
Ruled out by measurement, running the real node (Manual mode, positive_mode=Off):
- Pipe is a 9-tuple;
[0] Positiveis populated.RMStylesPipeOutunpacks it to[0] Positivecorrectly. - All eight return paths in
RMStylesFull.load_style— includingempty_resultand the free-prompt early return — emit an 8-tuple with positive at index 0. No ordering drift. js/rm_styles_overrides.jsonly hides/disables widgets. It never adds or removes any, so the positionalwidgets_valuesmapping is intact.
Actual finding — the content policy rewrites most of the library.
Measured across all 293 styles (THRESHOLD = 10):
| outcome | count | share |
|---|---|---|
| clean | 76 | 25.9% |
| sanitized | 206 | 70.3% |
| blocked | 11 | 3.8% |
74% of styles no longer emit their original positive. No positive is ever left empty —
blocked styles get PLACEHOLDER_POSITIVE instead, which is why this reads as "the wrong
text" rather than "nothing". Of the sanitized ones: median 95% of the text survives, but
the worst keep only 55% (e.g. #71 211→115 chars, #225 441→314, #83 243→178).
Open question: is this the reported bug (policy too aggressive / firing where it shouldn't), or is something else being observed downstream? The 11 blocked styles are the most visible — they emit placeholder text with nothing of the original.
Curiosity, low priority: sanitize() can lengthen a prompt (min delta −18 chars, max
104% kept). It rebuilds with ", ".join(kept), so a source using other separators comes
back slightly longer.
RM Styles: Random mode "picks the same styles over and over"
Reported: 2026-08-20 Nodes: RM Styles Full, RM Styles Full (Display), RM Styles Pipe Status: Investigated — original hypothesis (number rounding) NOT confirmed. Two real issues found, neither is the rounding.
Original hypothesis: the random prompt number is being rounded/manipulated into a
narrow range. Disproved. There is no float math anywhere in the path.
_get_random_prompt() uses random.choice() over a list of integer keys; the JS side
(js/rm_styles_full.js) does no random math at all in Random mode.
Evidence — measured, not reasoned. 602 real Random picks parsed out of
user/comfyui*.log, compared against 600 simulated runs of the node's own algorithm:
| metric | observed | simulated (correct picker) |
|---|---|---|
| max times any style picked (range 1–331, 321 draws) | 4 | 4 |
| styles never picked | 77 | 86 |
| per-style count variance | 0.781 | 0.891 |
| min gap between repeats | 31 | 31 (= history size + 1) |
Observed variance is slightly below random, i.e. the 30-item anti-repeat history is
working and the spread is marginally more even than chance. The picker is statistically
sound. Chart: C:\Users\rober\Playground\style-frequency.html
Real issue 1 — minimum/maximum widgets silently shrink the library.
candidates = [n for n in available_numbers if minimum <= n <= maximum]
(nodes/styles_full.py:65). Recent sessions ran minimum=150, maximum=330, which makes
133 of 293 styles unreachable. This is the actual cause of the perceived repetition —
the pool really is smaller, the picker is just faithfully sampling it. Also note style
#999 is an outlier in data/styles.json; any maximum below 999 excludes it, and the
next-highest real style is 331.
Real issue 2 (latent landmine) — the picker uses the global random module.
random.choice() at nodes/styles_full.py:76 shares Python's process-wide RNG. Many
ComfyUI packs call random.seed(seed) while they run (ComfyUI-Easy-Use's seed/wildcard
nodes, comfyui-frame-interpolation, ComfyUI-Hunyuan3DWrapper, basic_data_handling —
Easy-Use's own py/server.py:5 carries a comment acknowledging this). If any such node
reseeds with a fixed seed before the styles node executes, random.choice() returns
the same index every run and the anti-repeat history turns the picker into a closed
deterministic cycle of exactly RANDOM_HISTORY_SIZE + 1 = 31 styles. Reproduced:
distinct styles seen in 200 runs: 31
cycle: [232,233,234,235,236,237,238,240,...,268, 232,233,234,235,...] # repeats forever
That is precisely the reported symptom. It is not currently firing in the saved
workflows (none of them contain a reseeding node upstream), but it is one node away.
Fix: give the picker its own RNG — _RNG = random.Random() at module level, then
_RNG.choice(...) / _RNG.randint(...). Immune to anything another pack does.
Real issue 3 (minor) — "closest match" fallback silently reuses styles.
nodes/styles_full.py:245-248 snaps an unknown number to the nearest existing style. The
numbering has ~30 gaps (e.g. 42, 45, 48, 53 missing; nothing between 332 and 998), so in
Manual/Increment/Decrement modes a number landing in a gap silently repeats a neighbouring
style instead of erroring or skipping. Does not affect Random mode, where the number is
always drawn from existing keys.
Resolved
RM Styles: custom_json_path ignores quoted / relative / variable paths
Reported: 2026-08-07 Nodes: RM Styles Full, RM Styles Full (Display), RM Styles Pipe, Styles Editor modal
Symptom: Setting custom_json_path on an RM Styles node silently fell back to the
bundled data/styles.json, or logged Styles file not found for a file that exists.
Evidence (user/comfyui.log, 2026-08-07 09:40–09:43):
[RMStylesFull] Styles file not found: "C:\Users\rober\Documents\ComfyUI\ComfyUI\styles\Styles.csv"
The surrounding double quotes are part of the widget value — the log f-string adds none. That file exists on disk.
Root cause: The path string from the free-text widget was passed straight to Path().
custom_json_path.strip() removes whitespace only, so:
- Windows Explorer "Copy as path" quotes (
"C:\...") became part of the filename ~and%USERPROFILE%were never expanded- Relative paths resolved against ComfyUI's process CWD, not a predictable root
The node loader (_load_styles) and the editor API (_resolve_styles_file) each did their
own ad-hoc resolution, so they could also disagree about which file was being targeted.
Fix: Single shared _normalize_styles_path() in nodes/styles_full.py, used by both the
node loader and every editor API route. It strips whitespace, strips matched surrounding
quotes, expands ~ and environment variables, and resolves relative paths against the
ComfyUI base directory. Load failures now log the raw widget value alongside the resolved
path so a mismatch is visible.
Note: .csv styles files are still unsupported — the loader is JSON-only. A CSV path
now resolves correctly but fails at parse time with an explicit message.