Music generation record
41 — This Node Writes Down Why
- generation_json
MusicGenerationReceipt is a paperwork node. It builds one JSON string - generation_json - from four things you hand it, so the production record knows which settings were live, which model files were used, what score was generated and how long the audio actually came out.
You won't find it in the 3.0 example workflow, and that's not a reason to ignore it. MusicGeneration already emits a generation_json of its own, so the bundled graphs wire that directly. This node is the standalone path: when you're assembling the record yourself, or running generation through nodes that don't produce a record, this is where the pieces get joined.
The inputs
Four required, one optional, and only one of them is a judgment call.
settings_json- straight from the music settings node. Everything it recorded travels through.abc- the score. For a new YuE2 song that's the planner's output; for a cover it's the SheetSage2 transcription.model_files_json- which checkpoints were actually loaded.seconds- a float, and this is the one to get right. The node does not measure anything. It believes you. Wire the duration of the audio you actually generated.cover_source_json- optional; only used on the cover path.
What it does with them
It parses settings_json, merges in the model files and the measured duration, and then adds context depending on which song model the settings name.
If the settings carry a requested Length, you get a duration_result block: the target_seconds from your brief, difference_from_target_seconds for the real output, a boolean for whether the actual landed inside the requested range, and a note spelling out the philosophy - the requested length is approximate, finishing past the target is allowed inside max_duration, which is a separate ceiling. That's the whole point of the node. Requested length in these workflows is a musical aim, not a cutoff; the audio is never cropped, faded or padded to hit a number, and the receipt is how you see the gap instead of guessing at it.
For a cover, it records abc with an abc_source of "SheetSage2 audio transcription" plus the cover source record (filename, title, mode, encoder, byte size). For a plain YuE2 song it records the ABC along with the native planner values that produced it - the max_abc_tokens, temperature, top-p, top-k, repetition penalty and penalty window - so the score half of the pipeline is reproducible from the record alone.
Install
Same pack, same steps, nothing node-specific to download:
cd ComfyUI/custom_nodes
git clone https://github.com/jplenio/ComfyUI-MiniMax-Music-Production-Toolkit.git
cd ComfyUI-MiniMax-Music-Production-Toolkit
python -m pip install -r requirements.txt # same Python as ComfyUI
Restart and hard-refresh. If the pack imported fine but this node is missing, check the console for IMPORT FAILED - a half-installed dependencies list takes the whole pack down, not just one node.
Where people get burned
Feeding seconds from the ceiling rather than the measurement. Set yue2_max_duration to 360, wire 360 into this socket, and you've written a production record claiming a six-minute song that doesn't exist. Take the number from the audio.
The other trap is the boring one: this is a STRING passthrough in a graph where several nodes now emit JSON-shaped strings, and it is easy to wire settings_json into the wrong socket and get a record that validates and reads fine but describes a different run. When a production JSON looks subtly wrong - right song, wrong settings - the wire, not the node, is usually the culprit.
Keep it in the graph when you care about reproducibility. A pack that records requested versus actual duration, the model files, the effective settings for both engines and the score provenance is doing more than most music tooling does, and it costs you one node.
Inputs (5)
| Name | Type | Default | Description |
|---|---|---|---|
| settings_json | STRING | Configuration input 'settings json'. This value is passed directly to the node's processing logic; keep it at the workflow default unless you intentionally want to change that part of the production chain. | |
| abc | STRING | Configuration input 'abc'. This value is passed directly to the node's processing logic; keep it at the workflow default unless you intentionally want to change that part of the production chain. | |
| seconds | FLOAT | Configuration input 'seconds'. This value is passed directly to the node's processing logic; keep it at the workflow default unless you intentionally want to change that part of the production chain. | |
| model_files_json | STRING | Configuration input 'model files json'. This value is passed directly to the node's processing logic; keep it at the workflow default unless you intentionally want to change that part of the production chain. | |
| cover_source_jsonopt | STRING | Source audio identity and shared transcription mode from Cover song / Source audio. Used only for YuE2 Cover; the filename owns the final title. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| generation_json | STRING | — |