Skip to content

fix(mcp): re-open the flow under test by id in mcp-server (#1340) - #1341

Merged
Victor-w-Madeira merged 2 commits into
mainfrom
fix/issue-1340-mcp-server-reopen-by-id
Aug 6, 2026
Merged

fix(mcp): re-open the flow under test by id in mcp-server (#1340)#1341
Victor-w-Madeira merged 2 commits into
mainfrom
fix/issue-1340-mcp-server-reopen-by-id

Conversation

@Victor-w-Madeira

Copy link
Copy Markdown
Collaborator

Fixes #1340. Closes #1340.

Problem

Both re-opens in test 5 (mcp server tools should be refreshed when editing a server, @stable) clicked the first list-card whose name contained "New Flow". Langflow names every blank flow New Flow/New Flow (N), so under fullyParallel the shared project holds one per worker and .first() resolves whichever card the list puts first.

The issue asked to measure before assuming, and the measurement is the interesting part:

  • In isolation the test is correct. On a quiet instance its own flow ranks first (autosave keeps bumping updated_at), both re-opens land on the right id, and the daily history holds no recorded failure for this test. Latent, exactly as filed.
  • One competitor is enough. Seeding a single New Flow … in the same project before the list fetch flips it. Rendered order became ["New Flow probeB-p0d7n", "New Flow (1)", "Basic Prompting"]; the click opened the competitor (match=false), and the test then died on page.waitForSelector('text="MCP Tools"') at 30 s — an error blaming the MCP Tools node for a flow the test was never in. That is the same locator, and the same misdirected symptom, that cost auto-save-off.spec.ts two dailies before it was diagnosed ([Daily #1330] auto-save-off — reopening the just-created flow's card intermittently times out at 45 s (recurrent 2×) #1336).

Two dead ends worth recording, because both produced a false negative on the first try: a competitor created without folder_id lands in another project and never reaches this list, and a competitor created after the page's list fetch never triggers a refetch. Neither is a property of the spec — they were bugs in the probe.

Fix

Use openFlowById (#1214) for both re-opens. It is the repo's canonical by-id entry, and its own header already states the rule this spec was breaking: "Addressing the flow by id — never list-card.first() or a name-filtered list-card-open-button click — is what makes the entry parallel-safe." It also brings two guarantees the card click never had:

The flow id is read after the blank-flow navigation, never before it: the bootstrap reaches the templates modal through "New Flow", which parks the page on a placeholder flow Langflow deletes as soon as the modal navigates elsewhere (#490/#681).

The two awaitBootstrapTest(page, { skipModal: true }) hops are kept as-is. They are now redundant with openFlowById's own document load, but removing them would change how the test leaves the canvas — out of scope for a locator fix.

Scope note

No assertion changed. What the test proves is identical; it now proves it about the flow it actually created. helpers/mcp/open-add-mcp-server-modal.ts is deliberately not touched — see below.

Validation (nightly 1.12.0.dev18, --retries=0)

  • npm run typecheck ✅ · npx eslint <spec> ✅ (0 errors; 103 pre-existing style warnings)
  • Behavioral force-fail, the pair that matters:
    • pre-fix + one seeded competitor ⇒ FAILED 1/1 — opened the competitor, died at text="MCP Tools" (30 s)
    • post-fix + the same seeding ⇒ PASSED 3/3
  • Serial runs that reach the re-open: all passed; both re-opens verified landing on the created id (match=true) by instrumentation
  • No leak: 0 New Flow orphans and no test_server_* left on the instance after the runs (GET /api/v1/flows/, GET /api/v2/mcp/servers)

Honest caveat on the burst the issue asked for. A --workers=4 burst of this spec cannot validate the re-open, and did not: 3 of 4 runs failed at helpers/mcp/open-add-mcp-server-modal.ts:10 (mcp-server-dropdown, locator.click timeout) — always before the changed code. This is pre-existing and separately filed as #1335. Confirmed by a control run of the unmodified spec on main: same 2/3 pass rate, same step. Raising that budget from 3 s to 30 s locally did not help under --workers=2+ — the dropdown simply never becomes clickable when copies of this MCP spec run concurrently, which is a self-inflicted condition (the daily runs it once). That budget belongs to #1335 and to a shared helper with other callers, so it stays untouched here; the measurement is posted on #1335.

Both re-opens in "mcp server tools should be refreshed when editing a server"
clicked the first `list-card` whose name contained "New Flow". Langflow names
every blank flow "New Flow"/"New Flow (N)", so under `fullyParallel` the shared
project holds one per worker and `.first()` resolves whichever card the list
puts first.

Measured on nightly 1.12.0.dev18, and the measurement is the point: in
isolation the test's own flow ranks first and the click is correct, which is
why this never produced a recorded daily failure. Seeding ONE competing
"New Flow ..." in the same project before the list fetch flips it — the
rendered order became ["New Flow probeB-...", "New Flow (1)",
"Basic Prompting"], the click opened the competitor, and the test then died on
the `text="MCP Tools"` wait at 30 s, blaming the node for a flow it was never
in. The same locator cost `auto-save-off.spec.ts` two dailies before it was
diagnosed (#1336).

Use `openFlowById` (#1214) — the repo's by-id entry, whose own header states
that a name-filtered `list-card` click is exactly what makes an entry
parallel-unsafe. It adds two guarantees the card click never had: the
assistant-onboarding flag is seeded before the load, and the flow is gated on
being writable, which is the #1005 window where a mutation is silently
swallowed. This test mutates the flow it re-opens.

The id is read AFTER the blank-flow navigation, never before it: the bootstrap
reaches the templates modal through "New Flow", which parks the page on a
placeholder flow Langflow deletes as soon as the modal navigates elsewhere
(#490/#681).

No assertion changes: what the test proves is unchanged, it now proves it about
the flow it actually created.
Copilot AI lite review requested due to automatic review settings August 6, 2026 15:21
@Victor-w-Madeira Victor-w-Madeira added the follow-up Approved exception: follow-up of merged work (ROADMAP Intake) label Aug 6, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes a parallel-safety hazard in the MCP server regression spec by changing flow re-open steps to use the repo’s canonical by-id navigation helper (openFlowById) instead of selecting a flow card by a non-unique “New Flow” name.

Changes:

  • Update mcp-server.spec.ts to re-open the flow under test via openFlowById(page, flowId) for both re-open points.
  • Add logic to capture the flow id after creating the blank flow, and document the rationale in-line.
  • Update the spec doc (docs/mcp/server/mcp-server.md) to reflect the by-id re-open requirement and record the #1340 measurement/notes.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
tests/tests-automations/regression/mcp/server/mcp-server.spec.ts Replaces name-filtered flow-card reopen with openFlowById and introduces flow id tracking for the flow under test.
docs/mcp/server/mcp-server.md Aligns documentation with by-id reopen behavior and adds a note explaining the parallel hazard (#1340).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +794 to +809
// The flow under test has to be addressed by id from here on (#1340). The
// id is read AFTER this navigation, never before it: `awaitBootstrapTest`
// reaches the templates modal through "New Flow", which parks the page on a
// placeholder flow Langflow deletes as soon as the modal navigates
// elsewhere (#490/#681).
const placeholderUrl = page.url();
await page.getByTestId("blank-flow").click();
await page.waitForURL(
(url) =>
/\/flow\/[0-9a-f-]{36}/.test(url.pathname) &&
url.toString() !== placeholderUrl,
{ timeout: 30000 },
);
const flowUnderTest = new URL(page.url()).pathname.match(
/\/flow\/([0-9a-f-]{36})/,
)![1];

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Substantially right on both halves — addressed in cf27946, though not by replacing the URL read.

On the convention. You are correct that this file's Pattern-A note says only the POST /api/v1/flows 201 responses are trustworthy, and my placeholderUrl guard answered the staleness without answering that. But taking the id from the response instead is weaker here, and the reason is specific to this test: the page creates two flows — the bootstrap placeholder and the blank flow — so createdFlowIds holds both, and picking one means trusting the arrival order of two async resp.json() reads. The wrong pick is precisely the id Langflow deletes when the templates modal navigates away, which would reproduce #1340's symptom from the other direction.

Neither source alone is sufficient, so the fix now requires both: the URL says which flow the editor ended up on, and membership in the tracked 201 ids says this page created it and that it is persisted. A transient or client-only id cannot satisfy the membership test, which closes the residual gap in the URL read you point at.

On the 30 s hang. Fair, and fixed. The waitForURL became an expect.poll over the conjunction with an explicit message, so a blank-flow click that stops navigating fails at that step naming the cause instead of as a bare waitForURL timeout. Verified by mutating the predicate to an impossible id — the message does reach the report:

Error: the blank-flow click never landed the editor on a newly created flow: the URL
still holds the bootstrap placeholder, or its id is not among this page's
POST /api/v1/flows 201 responses

One correction to the premise, stated because the PR should not imply a defect it did not measure: the placeholder is not reused today. Measured 5/5 on nightly 1.12.0.dev18 — the blank-flow click issues its own POST /flows 201 and moves the URL every time. So this change is about convention-compliance and attribution, not about a hang anyone has hit.

Review feedback on PR #1341: deriving the flow under test from `page.url()`
alone sits against this file's own Pattern-A note, which says the canvas URL id
around the templates-modal hop is the stale bootstrap one and only the
`POST /api/v1/flows` 201 responses are trustworthy (#681/#505). The
"is it different from the placeholder URL" guard addressed the staleness but
not the convention, and it would spend 30 s in `waitForURL` before saying
anything if the click ever stopped navigating.

Neither source alone is sufficient here, so require both. The URL says which
flow the editor ended up on; membership in the tracked 201 ids says the page
actually created it and that it is persisted — which the raw URL cannot,
since this page creates the placeholder AND the blank flow, and picking one
from the id list means trusting the arrival order of two async body reads,
where the wrong pick is exactly the id Langflow deletes.

Polling the conjunction also fixes the attribution: a transient or client-only
id can never satisfy membership, and a blank-flow click that fails to navigate
now fails at that step naming the cause instead of as a bare waitForURL
timeout. Verified by mutating the predicate to an impossible id — the message
reaches the report.

No behaviour change on the happy path: measured 5/5 on nightly 1.12.0.dev18
that the blank-flow click issues its own POST /flows 201 and moves the URL, so
the placeholder is never reused.
@Victor-w-Madeira
Victor-w-Madeira merged commit 639897c into main Aug 6, 2026
18 of 21 checks passed
@Victor-w-Madeira
Victor-w-Madeira deleted the fix/issue-1340-mcp-server-reopen-by-id branch August 6, 2026 16:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

follow-up Approved exception: follow-up of merged work (ROADMAP Intake)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

mcp-server.spec.ts re-opens a flow by the name "New Flow" — same cross-worker hazard fixed in #1336

2 participants