Declared outputs are collected by the same mapping, in reverse
The output side of the manifest, with one distinction that matters: a node that produced null produced something, and is not the same as a node that produced nothing.
The rule
- Each declared output name resolves to the result the bound node produced on the bound port.
- Presence is decided by whether the key exists, so a null value counts as produced and is returned.
- An output whose node produced nothing at all is dropped from the result with a warning.
- A malformed output entry is skipped.
What it means
Presence is decided by whether the key exists, not by whether the value is
truthy. A node that produced null on its bound port produced something,
and that null is returned under the declared output name. That is different
from a node whose bound port never appears in what it produced at all — that
case is dropped from the result, with a warning, because there is nothing to
return.
A malformed entry — one missing its name, its node id or its port — is skipped without a warning: it never named a real output in the first place, so there is nothing to warn about.
Example
The workflow declares two outputs bound to the same node: answer, on its
text port, and hidden, on a debug port the node did not produce this
run.
{ "llm.1": { "text": null } }{ "answer": null }The debug port never appears in llm.1's results at all, so hidden is
dropped from the outputs, with a warning naming it. A malformed entry — an empty name, an empty node id, or an empty port — is
skipped the same way, but without the warning the dropped case above gets.