What happened?
WorkflowState.updateOperatorInputPorts(operatorId, numInputPorts) rebuilds an operator's inputPorts list but never touches links. When the count shrinks, a link whose target.portID referenced a now-removed port (e.g. input-1) is left in the graph as a dangling link pointing at a port that no longer exists.
Offending code — agent-service/src/agent/workflow-state.ts:173-194: the method sets the new inputPorts and emits a property-change event, but does not prune links targeting dropped ports.
Impact: latent — the method currently has no caller, so nothing triggers it yet. Once wired up (dynamic input-port editing), a shrink leaves links referencing missing ports, which can corrupt downstream portID-based resolution (e.g. toLogicalPlan's port-index lookup silently falls back to index 0).
Expected: on shrink, prune every link whose target port is no longer present, via deleteLink (so linkDeleteSubject fires).
How to reproduce?
Confirmed on main (agent-service, bun test). A test asserting the pruned result fails against current code:
const state = new WorkflowState();
state.addOperator(makeOperator("src"));
state.addOperator(makeOperator("op1", { inputPorts: [
{ portID: "input-0", displayName: "Input 0" },
{ portID: "input-1", displayName: "Input 1" },
]}));
state.addLink({ linkID: "l1",
source: { operatorID: "src", portID: "output-0" },
target: { operatorID: "op1", portID: "input-1" } });
state.updateOperatorInputPorts("op1", 1); // drops input-1
state.getAllLinks().map(l => l.linkID); // actual: ["l1"] — expected: []
Observed behavior was characterized in #7159 and dropped from that coverage PR; this issue tracks the fix.
What happened?
WorkflowState.updateOperatorInputPorts(operatorId, numInputPorts)rebuilds an operator'sinputPortslist but never toucheslinks. When the count shrinks, a link whosetarget.portIDreferenced a now-removed port (e.g.input-1) is left in the graph as a dangling link pointing at a port that no longer exists.Offending code —
agent-service/src/agent/workflow-state.ts:173-194: the method sets the newinputPortsand emits a property-change event, but does not prune links targeting dropped ports.Impact: latent — the method currently has no caller, so nothing triggers it yet. Once wired up (dynamic input-port editing), a shrink leaves links referencing missing ports, which can corrupt downstream
portID-based resolution (e.g.toLogicalPlan's port-index lookup silently falls back to index0).Expected: on shrink, prune every link whose
targetport is no longer present, viadeleteLink(solinkDeleteSubjectfires).How to reproduce?
Confirmed on
main(agent-service,bun test). A test asserting the pruned result fails against current code:Observed behavior was characterized in #7159 and dropped from that coverage PR; this issue tracks the fix.