fix(frontend): validate edge source/target before adding connection - #14271
fix(frontend): validate edge source/target before adding connection#14271minderm wants to merge 1 commit into
Conversation
WalkthroughChangesMCP edge validation
Estimated code review effort: 3 (Moderate) | ~20 minutes Suggested reviewers: Important Pre-merge checks failedPlease resolve all errors before merging. Addressing warnings is optional. ❌ Failed checks (1 error, 2 warnings)
✅ Passed checks (6 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/frontend/src/utils/__tests__/cleanEdges.test.ts`:
- Line 1000: Update the tests around the local cleanEdges helper to import and
invoke the exported production cleanEdges and filterHiddenFieldsEdges
implementations from reactflowUtils instead. Remove or bypass the duplicate
local implementations so the cases at all referenced locations validate
production behavior, including handlesMatch and advanced-field handling, rather
than only smoke-testing a divergent test helper.
- Line 106: Update the targetHandle extraction in the cleanEdges test to narrow
or cast edge.data to an object shape containing an optional targetHandle before
accessing the property, then retain TargetHandleType for the resulting value. Do
not access targetHandle directly while EdgeType.data remains unknown.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 30ba67a7-6107-4464-9f53-43ca467b7f7e
📒 Files selected for processing (2)
src/frontend/src/utils/__tests__/cleanEdges.test.tssrc/frontend/src/utils/reactflowUtils.ts
| // MCP server. Before the schema loads, dynamic fields may have show: false. | ||
| // Removing edges in that transient state causes false positives. | ||
| const isMcpComponent = targetNode.data.type === "MCPTools"; | ||
| const targetHandle = _edge.data?.targetHandle as TargetHandleType | undefined; |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
rg -n -C 3 'data\?: unknown|_edge\.data\?\.targetHandle' \
src/frontend/src/utils/__tests__/cleanEdges.test.tsRepository: langflow-ai/langflow
Length of output: 777
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== file excerpt =="
sed -n '70,140p' src/frontend/src/utils/__tests__/cleanEdges.test.ts | cat -n
echo
echo "== tsconfig/frontend package type-check scripts =="
for f in package.json src/frontend/package.json tsconfig.json src/frontend/tsconfig.json; do
if [ -f "$f" ]; then
echo "--- $f ---"
sed -n '1,220p' "$f"
fi
done
echo
echo "== TypeScript availability and parser check =="
command -v tsc || true
node - <<'JS'
try {
const ts = require('typescript')
const source = `
interface EdgeType {
selected?: boolean;
animated?: boolean;
data?: unknown;
}
const _edge: EdgeType = {};
const targetHandle = _edge.data?.targetHandle as string | undefined;
`
const sf = ts.createSourceFile('probe.ts', source, ts.ScriptTarget.Latest, true)
const program = ts.createProgram(['probe.ts'], {})
const diagnostics = ts.getPreEmitDiagnostics(program)
console.log(JSON.stringify({
hasTs: true,
diagnostics: diagnostics.map(d => ({
code: d.code,
message: ts.flattenDiagnosticMessageText(d.messageText, '\n'),
start: d.file ? sf.getLineAndCharacterOfPosition(d.start) : null
}))
}, null, 2))
} catch (e) {
console.log(JSON.stringify({hasTs: false, error: String(e && e.message || e)}, null, 2))
}
JSRepository: langflow-ai/langflow
Length of output: 12300
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== file excerpt =="
sed -n '70,140p' src/frontend/src/utils/__tests__/cleanEdges.test.ts | cat -n
echo
echo "== tsconfig/frontend package type-check scripts =="
for f in package.json src/frontend/package.json tsconfig.json src/frontend/tsconfig.json; do
if [ -f "$f" ]; then
echo "--- $f ---"
sed -n '1,220p' "$f"
fi
done
echo
echo "== Type narrowing probe =="
node - <<'JS'
const code = `_edge.data?.targetHandle`
console.log(`TypeScript optional-chaining narrowing behavior for data?: unknown cannot be reliably checked without TS compiler/tooling in this environment; the repository does expose data?: unknown upstream.`)
JSRepository: langflow-ai/langflow
Length of output: 12366
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== cleanEdges test file size and imports near top =="
wc -l src/frontend/src/utils/__tests__/cleanEdges.test.ts
sed -n '1,26p' src/frontend/src/utils/__tests__/cleanEdges.test.ts | cat -n
echo
echo "== static probe: unknown data followed by optional property access in EdgeType =="
python3 - <<'PY'
from pathlib import Path
p = Path("src/frontend/src/utils/__tests__/cleanEdges.test.ts")
text = p.read_text()
print(EdgeType := text[text.find("interface EdgeType"): text.find("// Simplified filterHiddenFieldsEdges mock")])
print("data access line:", text[text.find("const targetHandle ="): text.find("const targetHandle =")+-1])
print("contains TargetHandleType import:", "TargetHandleType" in text[:text.find("_edge.data?.targetHandle")])
PYRepository: langflow-ai/langflow
Length of output: 1533
Type edge.data before reading targetHandle.
EdgeType.data is still unknown, and the helper narrows it down before asserting TargetHandleType. Cast/narrow the optional chain instead, or give data a targetHandle?: TargetHandleType shape.
Proposed fix
- const targetHandle = _edge.data?.targetHandle as TargetHandleType | undefined;
+ const targetHandle = (
+ _edge.data as { targetHandle?: TargetHandleType } | undefined
+ )?.targetHandle;📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const targetHandle = _edge.data?.targetHandle as TargetHandleType | undefined; | |
| const targetHandle = ( | |
| _edge.data as { targetHandle?: TargetHandleType } | undefined | |
| )?.targetHandle; |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/frontend/src/utils/__tests__/cleanEdges.test.ts` at line 106, Update the
targetHandle extraction in the cleanEdges test to narrow or cast edge.data to an
object shape containing an optional targetHandle before accessing the property,
then retain TargetHandleType for the resulting value. Do not access targetHandle
directly while EdgeType.data remains unknown.
| targetHandle, | ||
| }; | ||
|
|
||
| const result = cleanEdges([parserNode, mcpNode], [edge]); |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Run these cases against the exported implementation.
These tests call this file’s local cleanEdges (Line 120), not src/frontend/src/utils/reactflowUtils.ts’s exported function. The duplicate already diverges from production (handlesMatch and advanced-field handling), so the new cases do not prove the PR behavior. Import and invoke the production cleanEdges/filterHiddenFieldsEdges instead. As per coding guidelines, frontend tests must “verify meaningful behavior for new functionality rather than only smoke-testing it.”
Also applies to: 1074-1074, 1143-1143
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/frontend/src/utils/__tests__/cleanEdges.test.ts` at line 1000, Update the
tests around the local cleanEdges helper to import and invoke the exported
production cleanEdges and filterHiddenFieldsEdges implementations from
reactflowUtils instead. Remove or bypass the duplicate local implementations so
the cases at all referenced locations validate production behavior, including
handlesMatch and advanced-field handling, rather than only smoke-testing a
divergent test helper.
Source: Coding guidelines
Description
cleanEdgesto skip edges with missing source/targetChanged files
src/frontend/src/utils/reactflowUtils.ts— validation logic incleanEdgessrc/frontend/src/utils/__tests__/cleanEdges.test.ts— unit testsHow to test
Checklist
Summary by CodeRabbit