plotly/plotly.js · warning
Circular Sankey diagrams do not support the "input" <type>.s
Error message
Circular Sankey diagrams do not support the "input" <type>.sort mode; falling back to the default sort.
What it means
In src/traces/sankey/render.js:79, applyInputSort detects `node.sort` or `link.sort` set to 'input' while the sankey graph is circular (loops detected). d3-sankey's input-order sorting is incompatible with the circular layout algorithm, so Plotly warns and falls back to the default sort, meaning the rendered order will not preserve the input order.
Source
Thrown at src/traces/sankey/render.js:79
sankey = d3Sankey.sankey();
}
sankey
.iterations(c.sankeyIterations)
.size(horizontal ? [width, height] : [height, width])
.nodeWidth(nodeThickness)
.nodePadding(nodePad)
.nodeId(function(d) {
return d.pointNumber;
})
.nodeAlign(nodeAlign)
.nodes(nodes)
.links(links);
function applyInputSort(type) {
if (trace[type].sort === 'input') {
if (circular) {
Lib.warn(
`Circular Sankey diagrams do not support the "input" ${type}.sort mode; falling back to the default sort.`
);
} else {
// Passing null maintains the input order
sankey[`${type}Sort`](null);
}
}
}
applyInputSort('link');
applyInputSort('node');
var graph = sankey();
if(sankey.nodePadding() < nodePad) {
Lib.warn('node.pad was reduced to ', sankey.nodePadding(), ' to fit within the figure.');
}
// Counters for nested loopsView on GitHub (pinned to 1d090e0b5f)
Solutions
- Remove the 'input' sort or accept the default sort for circular diagrams.
- Break the cycle in your links so the graph is acyclic if input order matters, then keep sort: 'input'.
- Reorder the node/link arrays in the data itself, since order can be conveyed without the sort flag.
Example fix
// before
node: { sort: 'input' }, links: [ {source:0,target:1}, {source:1,target:0} ]
// after
node: { sort: 'input' }, links: [ {source:0,target:1} ] // cycle removed; or drop sort for circular graphs Defensive patterns
Strategy: validation
Validate before calling
function sankeyIsAcyclic(nodes, links) {
const idSet = new Set(nodes.map((_, i) => i));
const adj = new Map(links.map(l => [l.source, []]));
links.forEach(l => adj.get(l.source)?.push(l.target));
const state = new Array(nodes.length).fill(0);
let cyclic = false;
(function dfs(u) {
if (state[u] === 1) { cyclic = true; return; }
if (state[u] === 2) return;
state[u] = 1;
(adj.get(u) || []).forEach(dfs);
state[u] = 2;
})([...idSet][0]);
return !cyclic;
}
// only set sort: 'input' if sankeyIsAcyclic(nodes, links) Type guard
function supportsInputSort(circular, trace) {
return !circular && (trace.node.sort === 'input' || trace.link.sort === 'input');
} Prevention
- Detect cycles in your link data before requesting sort: 'input'.
- Do not rely on 'input' sort for circular sankey diagrams; encode order in array order instead.
- Check the plotly.js changelog when enabling circular sankey features.
When it happens
Trigger: Setting trace.node.sort: 'input' (or link.sort: 'input') on a sankey trace whose links form a cycle, so `circular` is true in the layout computation.
Common situations: Energy/cycle-flow diagrams (money loops, feedback loops) styled with input sort for deterministic ordering; users upgrading plotly.js to a version that added circular sankey support and discovering the sort flag is ignored.
Related errors
- Invalid color specifier: "${cstr}". Defaulting to "#000"
- Node <nodeIndex> is already part of a group.
- node.pad was reduced to <sankey.nodePadding()> to fit withi
AI-assisted analysis of plotly/plotly.js@1d090e0b5f (2026-09-02).
Data as JSON: /api/errors/71a617298f8d1722.
Report an issue: GitHub.