MOSS BBOX Canvas
The big drawing board, and what canvas_data actually is
- canvas_data
- width
- height
If you searched for this and got a node that's mostly a blank rectangle with one long unreadable JSON box at the bottom, that's normal. MOSS BBOX Canvas is the drawing half of a two-node pair for MOSS-Image, and the JSON widget is not something you're supposed to type into.
Here's the short version before you wire anything: this is the legacy canvas. It still loads, still works, and existing workflows keep running, but the author marks it deprecated in favor of MOSSSharedCanvas plus MOSS BBOX Export. If you're starting fresh, read the shared-canvas article instead. If you opened someone's older workflow and this node is in it, stay - the mechanics are identical.
Why a canvas node exists at all
MOSS-Image (like Ideogram 4 before it) was trained to read structured captions: a summary, plus a list of items that each carry a label and a bounding box in centralized pixel yxyx coordinates. When a model's caption schema includes geometry, plain prose underperforms badly - that's the whole reason canvas prompt-builders keep appearing, the same pattern Kijai's Ideogram 4 Prompt Builder filled for that model. Hand-writing {"bbox":[-592,-448,592,448]} for four subjects is miserable. Drawing four rectangles with a mouse is not.
MOSS BBOX Canvas is the mouse half. It gives you a 7-color palette (red, blue, yellow, green, magenta, cyan, orange), per-box type, a grid, Show Boxes / Draw / Reset, and latent dimensions - and it hands the result downstream as data.
What it actually does under the hood
Almost nothing, and that's a compliment. The node has exactly one input, moss_state, a multiline STRING whose default is a serialized {"schema_version":"moss_bbox_v1", ...} blob. The bundled JavaScript canvas owns that widget: when you draw, move, resize or retype, it writes the whole state back into the string. At queue time the Python side parses it and hands it back out.
The parsing is where the guardrails live, so it's worth knowing what it rejects:
widthandheightmust be positive multiples of 16. Not a style preference - ComfyUI's Empty Flux 2 Latent does integer division by 16, so the pack refuses sizes that would get silently truncated.- Box ids must be non-empty and unique, each box's
slotmust be one of the seven colors, and itslabelmust becharacter,objectortext. - Coordinates must be finite numbers. Zero-area and out-of-canvas boxes are allowed through, just warned about later at export.
Inputs, outputs, wiring
Input: moss_state only. Resist the urge to edit it by hand; you'll break the unique-id rule and get a ValueError instead of a prompt.
Outputs:
canvas_data- typeMOSS_BBOX_LAYOUT, pure JSON of the state. This goes into MOSS BBOX Prompter (Hybrid)'scanvas_datainput, which is the node that turns boxes plus words into an actual prompt.widthandheight- plain INTs. Wire both into Empty Flux 2 Latent (right-click the widgets → Convert to input if they're not already sockets). Keep both connected; a mismatched latent size and canvas size is the most common "my boxes are shifted" cause.
Default is 896×1184, portrait, which is what the bundled examples use.
Install
Nothing exotic: no pip dependencies at all (pyproject.toml declares an empty dependency list), and the package downloads no models. You need a ComfyUI build with MOSS-Image support and the MOSS-Image weights, plus the LoRA if you're running the DMD example.
cd ComfyUI/custom_nodes
git clone https://github.com/ukr8b3g-cmyk/MossImage-BBOX-Prompter.git
# restart ComfyUI, then Ctrl+F5 in the browser
ComfyUI-Manager works too, via Install via Git URL with that same address. Refreshing the browser is not optional - the canvas is a DOM widget, so a stale frontend shows you a naked string field with no drawing surface.
Where people get stuck
Two nodes, same name. MOSSBBoxCanvas and MOSSSharedCanvas both display as "MOSS BBOX Canvas" in search, and MOSSBBoxPrompter shows as "MOSS BBOX Prompter (Hybrid)" while the current one drops the parenthetical. Search results mark the old ones deprecated. The quick rule: legacy canvas outputs canvas_data and pairs with the Prompter; current canvas outputs framing_data and pairs with Export.
"width must be a positive multiple of 16." You typed 900 in the size fields, or a preset from somewhere else. Round to 896/1184 or another multiple of 16.
"Expected MOSS state schema_version=moss_bbox_v1." You pasted a layout JSON exported by something else into moss_state. That field isn't an interchange format - for importing external layouts, the current canvas has a JSON import dialog. This node doesn't.
Last thing, and it matters more than any of the above: boxes are guidance. In the author's own testing a centered suitcase drifted toward the person in the scene on one seed. Treat this as strong composition steering, not inpainting.
Inputs (1)
| Name | Type | Default | Description |
|---|---|---|---|
| moss_state | STRING | {"schema_version":"moss_bbox_v1","prompt":"","width":896,"height":1184,"slots":{"red":"","blue":"","yellow":"","green":"","magenta":"","cyan":"","orange":""},"boxes":[],"settings":{"auto_position":false,"active_slot":"red","draw_mode":false,"selected_id":null}} | — |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| canvas_data | MOSS_BBOX_LAYOUT | — |
| width | INT | — |
| height | INT | — |