Skip to content

fix(frontend): fold what the migration rehearsal found into the page - #15624

Open
ogabrielluiz wants to merge 3 commits into
feat/migration-page-copy-decisionsfrom
fix/migration-page-rehearsal-findings
Open

ogabrielluiz wants to merge 3 commits into
feat/migration-page-copy-decisionsfrom
fix/migration-page-rehearsal-findings

Conversation

@ogabrielluiz

@ogabrielluiz ogabrielluiz commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

Stacked on the PR below it. A rehearsal of the whole move, in a real browser on real instances, found these on Settings > Migration. They touch steps whose PRs are already approved, so they come as one PR on top of the page stack. It needs the three new refusal codes from the API PRs further down the stack.

What it fixes

The document itself could scroll and hide the top bar and the paused banner. Each locked step holds a line that only a screen reader hears. It is positioned out of the flow, and nothing between it and the document was positioned, so each one was placed against the document at its place in the list. With steps below the fold the document grew taller than the window. A focus or a find in page could then scroll the document, and the wheel could not bring it back. The page's root is positioned now, so those lines stay inside the settings scroll area.

The knowledge bases test of "Where your data goes" told every admin to ask the database admin for an extension. It now has a line for each of three reasons. The database lacks the pgvector extension. This Langflow server lacks the pgvector package, which a plain install does not include: install it, restart Langflow, test again. Or the instance already runs on PostgreSQL and its server has no PGVECTOR_CONNECTION_STRING: set it to that database, restart Langflow, test again. That last line is the action alone, because the note above it already says where the knowledge bases go. The server's own words stay under each line.

On an instance that already runs on PostgreSQL, the note in that section said knowledge bases are copied into the new instance's database. There they go to the store this server reads them from, the one that variable names, and the note says so.

"Copy knowledge bases" reads the missing variable too, as the reason the step is blocked and as the refusal of its start. It has a line of its own there. The note above it says the store changes and does not say which one, so the line names the store before it asks for the variable, and it ends with the copy.

A pause that is refused because changes already under way had not finished says to try again in a moment. Trying again does not ask a second time, since the admin already agreed to this pause.

A copy that ran keeps its place when a step before it opens again, for example when the check fails again during the pause. The server refuses to start it then, and the page still offered "Copy again" and answered with its line for a failure it cannot name. A copy step now offers no start, real or test, while a step before it is neither done nor skipped, and says "Finish the steps above first." where the buttons were. That line is a status, and it takes the focus when the buttons it replaces held it. A tab that has not read the new state yet can still send a start, and it gets the same line. The line under a ticked option now reads "This applies to the next copy.", because "Copy again for this to apply." was wrong after a test run, when no copy exists yet.

Try it

On /settings/migration, in the console: document.querySelector('[data-testid="migration-step-check_target"]').scrollIntoView(), then document.scrollingElement.scrollTop. It reads 0, and the top bar stays where it is.

On a Langflow server without the pgvector package, with a knowledge base on its disk, click "Test and save" in "Where your data goes". The Knowledge bases section says the package is missing.

Pause, make the copies, then make the check fail again, for example by removing the bytes of a listed file and running the check again. Open "Copy the database". It shows what it copied and "Finish the steps above first.", with no button.

How it was tested

Jest has 10 new tests: the three reasons of the knowledge bases test, each in its section with the server's words under it and the database field left unmarked, the note on a PostgreSQL instance, the blocked copy step and its refused start in the step's own words, and the refused pause with its second try. The last three are for the copy steps: no start while a step before it is open again, the start that stays when every step before it is done or not needed, and the locked refusal in the step's words. Two are for the focus: it moves to the line when the gate closes under a focused start, and it stays where it is otherwise. I planted 23 defects in this PR's code, one at a time, and a Jest test fails for each. The whole Jest suite of the frontend passes with this PR.

The walks check the rest in a browser against a real backend. migration-checks.spec.ts, which runs in CI, scrolls the last step into view and checks the document did not move. Without the fix that read 508 at 1280x720. migration-pause.spec.ts confirms the backup with no place named: the field takes the focus, the browser shows its own required-field message and nothing is confirmed. The form already worked that way, and the walk now says so. migration-prepare.spec.ts passes on an instance that has knowledge bases, where its "Ready." matched two lines before.

By hand against real servers, I saw each of the new lines. On an instance that already runs on PostgreSQL, with a knowledge base on its disk and no PGVECTOR_CONNECTION_STRING, "Where your data goes" showed the new note and the line that asks for the variable, with the server's words under it. With the variable set the test passed, and the instance went on to the copies. With the server started again without it, "Copy knowledge bases" read its own line for the missing variable, and its start was refused with it. For the missing package I hid pgvector from one server process, and the Knowledge bases section said the package is missing while the database field stayed unmarked. With the three copies made and the check made to fail again, each copy row opened with its result and "Finish the steps above first.", and offered no start. A second tab that still showed "Copy again" had its start refused as locked and showed the same line.

npm run check:i18n passes with the 5 new strings in all 8 locales. Each sits next to the strings of its own step. One string of the decisions PR is reworded in all 8. Biome is clean on the touched files, and the type check shows no new error.

Summary by CodeRabbit

  • Bug Fixes
    • Migration copy and test-run controls are now available only after all preceding steps are complete or skipped, with a clear status shown when steps remain.
    • Pause failures caused by active requests now explain the issue and allow an immediate retry.
    • PostgreSQL knowledge-base migration guidance now clarifies destination and setup requirements, with distinct messages for missing configuration or the pgvector package.
    • Updated migration messages across supported languages to clarify that accepted choices apply to the next copy.

@coderabbitai

coderabbitai Bot commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration
  • Configuration used: Repository: langflow-ai/langflow/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: bb02e0c6-5814-4f0f-94fb-32789d37251e

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository: langflow-ai/langflow/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 0fca0d3f-b5c6-4eed-8a5f-fcc2fef498d8

📥 Commits

Reviewing files that changed from the base of the PR and between a7cf5bc and 66a9f06.


📒 Files selected for processing (19)
  • .secrets.baseline
  • src/frontend/src/locales/de.json
  • src/frontend/src/locales/en.json
  • src/frontend/src/locales/es.json
  • src/frontend/src/locales/fr.json
  • src/frontend/src/locales/ja.json
  • src/frontend/src/locales/ko.json
  • src/frontend/src/locales/pt.json
  • src/frontend/src/locales/zh-Hans.json
  • src/frontend/src/pages/SettingsPage/pages/MigrationPage/CopyStep.tsx
  • src/frontend/src/pages/SettingsPage/pages/MigrationPage/DestinationsStep.tsx
  • src/frontend/src/pages/SettingsPage/pages/MigrationPage/PauseStep.tsx
  • src/frontend/src/pages/SettingsPage/pages/MigrationPage/__tests__/catalog.test.ts
  • src/frontend/src/pages/SettingsPage/pages/MigrationPage/__tests__/steps.test.tsx
  • src/frontend/src/pages/SettingsPage/pages/MigrationPage/catalog.ts
  • src/frontend/src/pages/SettingsPage/pages/MigrationPage/index.tsx
  • src/frontend/tests/core/features/migration-checks.spec.ts
  • src/frontend/tests/core/features/migration-pause.spec.ts
  • src/frontend/tests/core/features/migration-prepare.spec.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 5 remain after this review.



Walkthrough

The migration settings page adds PostgreSQL knowledge-base destination guidance, distinguishes pgvector probe errors, gates copy controls on earlier step status, and supports retrying a pause after active requests are reported. Locale text and migration tests are updated for these changes.

Changes

Migration settings

Layer / File(s) Summary
PostgreSQL knowledge-base guidance
src/frontend/src/pages/SettingsPage/pages/MigrationPage/DestinationsStep.tsx, src/frontend/src/pages/SettingsPage/pages/MigrationPage/catalog.ts, src/frontend/src/pages/SettingsPage/pages/MigrationPage/__tests__/*, src/frontend/tests/core/features/migration-prepare.spec.ts, src/frontend/src/locales/*.json, .secrets.baseline
The destination note now distinguishes SQLite from other database types. Probe and copy codes map missing pgvector package or environment settings to dedicated messages. Locale text describes the PostgreSQL storage configuration, and tests cover probe results and destinations. The baseline records updated locale line numbers.
Copy-step gating and guidance
src/frontend/src/pages/SettingsPage/pages/MigrationPage/CopyStep.tsx, src/frontend/src/pages/SettingsPage/pages/MigrationPage/catalog.ts, src/frontend/src/pages/SettingsPage/pages/MigrationPage/__tests__/*, src/frontend/src/pages/SettingsPage/pages/MigrationPage/index.tsx, src/frontend/tests/core/features/migration-checks.spec.ts, src/frontend/src/locales/*.json
Copy and test-run controls are available only when preceding steps are done or skipped. When the gate closes, the status message can receive focus if a start control had focus. The catalog and tests cover locked steps. Locale text now says an accepted choice applies to the next copy. The migration page container uses relative positioning.
Pause retry for active requests
src/frontend/src/pages/SettingsPage/pages/MigrationPage/PauseStep.tsx, src/frontend/src/pages/SettingsPage/pages/MigrationPage/__tests__/steps.test.tsx, src/frontend/tests/core/features/migration-pause.spec.ts, src/frontend/src/locales/*.json
When requests remain active, the pause flow displays a dedicated message and allows a direct retry. Locale text and tests cover this refusal and retry. The browser test also checks focus and validation when the backup location is empty.

Priority: ⬇️ Low

Estimated code review effort: 3 (Moderate) | ~25 minutes

Change: Bug fix

Merge Risk: ⚪ Minimal · up to 66a9f

The migration-page changes are mergeable after normal checks.

🚥 Pre-merge checks | ✅ 8 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 4 functions across 10 files. (9 skipped: … Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (8 passed)
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title identifies frontend fixes based on migration rehearsal findings. It is concise and related to the main changes, although it does not name the specific migration behaviors addressed.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Test Coverage For New Implementations Passed The PR includes focused regression coverage for the changed migration behavior. steps.test.tsx covers PostgreSQL destination guidance, the three pgvector refusal cases, pause retry without a second …
Test Quality And Coverage Passed The PR adds behavior-focused Jest/React Testing Library coverage for the new destination refusal messages, PostgreSQL PGVECTOR_CONNECTION_STRING guidance, pause retry behavior, copy-step gating, ski…
Test File Naming And Structure Passed All changed tests follow the required conventions. Unit tests are catalog.test.ts and steps.test.tsx under src/frontend/src/.../__tests__, use Jest and React Testing Library, and include descrip…
Excessive Mock Usage Warning Passed PASS. The PR adds only two targeted api.post rejection stubs for server refusal responses. The tests render the real PauseStep and CopyStep components and verify their UI and retry behavior. The…

Full details: Docstring Coverage

Explanation

Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 4 functions across 10 files. (9 skipped: 9 unsupported.)



✨ Finishing Touches 💡 2
📝 Generate docstrings 💡
  • Commit to this branch
  • Create a new PR

🛠️ Fix failing CI checks 💡
  • Commit to this branch
  • Create a new PR

🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR


  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

✅ Test Coverage Advisor

No source changes detected without accompanying tests. Thanks for keeping coverage up! 🎉

Advisory check only — never blocks merge.

@github-actions github-actions Bot added the bug Something isn't working label Oct 7, 2026
@github-actions

github-actions Bot commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

Frontend Unit Test Coverage Report

Coverage Summary

Lines Statements Branches Functions
Coverage: 59%
59.71% (98417/164820) 74.23% (15404/20749) 54.96% (2446/4450)

Unit Test Results

Tests Skipped Failures Errors Time
7465 0 💤 0 ❌ 0 🔥 23m 19s ⏱️

@codecov

codecov Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 68.80%. Comparing base (a7cf5bc) to head (66a9f06).

Additional details and impacted files

Impacted file tree graph

@@                          Coverage Diff                           @@
##           feat/migration-page-copy-decisions   #15624      +/-   ##
======================================================================
- Coverage                               68.80%   68.80%   -0.01%     
======================================================================
  Files                                    2769     2769              
  Lines                                  298493   298484       -9     
  Branches                                43156    43152       -4     
======================================================================
- Hits                                   205374   205365       -9     
  Misses                                  90625    90625              
  Partials                                 2494     2494              
Files with missing lines Coverage Δ
...tingsPage/pages/MigrationPage/DestinationsStep.tsx 90.73% <ø> (-0.03%) ⬇️
...ges/SettingsPage/pages/MigrationPage/PauseStep.tsx 88.49% <ø> (-0.19%) ⬇️
.../pages/SettingsPage/pages/MigrationPage/catalog.ts 94.31% <ø> (ø)
...c/pages/SettingsPage/pages/MigrationPage/index.tsx 84.25% <ø> (-0.03%) ⬇️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions github-actions Bot added bug Something isn't working and removed bug Something isn't working labels Oct 7, 2026

@Cristhianzl Cristhianzl left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

⚠️ Important (preferably this PR)

I1 — The copy step's new line was written as if no note stood above it, and one does

File: src/frontend/src/pages/SettingsPage/pages/MigrationPage/CopyStep.tsx:160-163 and :177-187; string settings.migration.kb.postgresEnv

Issue: The PR body justifies the shape of the new line explicitly — "No note stands above it, so the line says why as well, and it ends with the copy" — and the new test repeats the premise in a comment: "No note stands above this one, so it says why as well." The premise does not hold. The step renders a note under exactly the condition that produces the refusal:

{step === "copy_knowledge_bases" &&
  migration.instance.database.type === "postgresql" && (
    <p className="text-sm">{t("settings.migration.kb.postgresNote")}</p>
  )}

pgvector_env_missing comes from _unreadable_here (src/backend/base/langflow/api/v1/migration.py:941-948), which is postgresql and not postgres_env_configured() — so the note is always above the new line, never sometimes. What the admin reads is:

This instance uses PostgreSQL, so it switches to the new store too. Restoring the backup undoes it.
This instance already uses PostgreSQL, so its knowledge bases are copied to the store this server reads them from. Set PGVECTOR_CONNECTION_STRING on this server to that database and restart Langflow, then copy again.

Why it matters: The clause that was deliberately dropped from probe.pgvectorEnv — on the correct grounds that the note above it carries the "where they go" — was deliberately kept in kb.postgresEnv on grounds that are false. So the one surface that duplicates is the one that was reasoned about as not duplicating, in all 8 locales. It also means a reader comparing the two strings will conclude the asymmetry is intentional and leave it.

Suggested fix: Shorten kb.postgresEnv to the action alone — the same decision already taken for probe.pgvectorEnv — since kb.postgresNote is the note above it. Then add the missing assertion to the new test, which currently renders the duplicated state and says nothing about it:

expect(screen.queryByText(/^This instance uses PostgreSQL/)).toBeInTheDocument();
expect(screen.getByRole("alert").firstElementChild).toHaveTextContent(/^Set PGVECTOR_CONNECTION_STRING/);

If the duplication is wanted after all — because the alert may be read on its own by a screen reader while the note is plain text — say that in the comment above the COPY_CODES entry, so the next person does not "fix" it.


I2 — The new gate unmounts the button the admin may be standing on, and nothing announces what replaced it

File: src/frontend/src/pages/SettingsPage/pages/MigrationPage/CopyStep.tsx:275-318

Issue: reached ? <buttons> : <p> removes the start buttons from the DOM. The transition happens asynchronously, not on a user action: useMigrationQuery polls every 5 s while a check is running (src/frontend/src/controllers/API/queries/migration/use-migration.ts:29-32), and useStartCopyMutation invalidates on onSettled (:180-181). Both are the rehearsal scenario from the body — another admin re-runs the check, or this tab's start comes back 409 locked. A keyboard user focused on "Copy again" has focus dropped to <body>, and the line that replaced it is a plain paragraph in no live region:

) : (
  <p className="text-sm">{t("settings.migration.notStarted")}</p>
)}

Why it matters: This is the exact failure mode the same file refuses elsewhere, with the reason written down at CopyStep.tsx:353: "aria-disabled, since native disabled would drop the keyboard user's focus to <body>." The gate is new behaviour introduced here, so the regression is this diff's. The two new Jest tests assert the rendered text in a static state and never drive the reached: true → false transition — both pass migration.steps arrays that are fixed for the life of the test — so nothing would catch it.

Suggested fix: Keep the buttons mounted and apply the pattern the file already uses — aria-disabled, a guarded onClick, and aria-describedby pointing at the notStarted line — or, if they should really disappear, give the paragraph role="status" and move focus to it. Either way, add a test that re-renders the same component with an earlier step flipped from done to blocked and asserts where focus landed; that is the assertion that fails without the fix.

@github-actions github-actions Bot added the lgtm This PR has been approved by a maintainer label Oct 7, 2026
@ogabrielluiz
ogabrielluiz force-pushed the fix/migration-page-rehearsal-findings branch from b9db7ac to 9e814fc Compare October 7, 2026 14:57
@github-actions github-actions Bot added bug Something isn't working and removed bug Something isn't working labels Oct 7, 2026
@ogabrielluiz
ogabrielluiz force-pushed the fix/migration-page-rehearsal-findings branch from 9e814fc to 94af7f1 Compare October 7, 2026 22:46
@github-actions github-actions Bot added bug Something isn't working and removed bug Something isn't working labels Oct 7, 2026
@ogabrielluiz
ogabrielluiz force-pushed the fix/migration-page-rehearsal-findings branch from a4be90a to 66a9f06 Compare October 9, 2026 14:18
@github-actions github-actions Bot added bug Something isn't working and removed bug Something isn't working labels Oct 9, 2026
@ogabrielluiz
ogabrielluiz added this pull request to stack #15675 October 9, 2026 15:18
@github-actions github-actions Bot added bug Something isn't working and removed bug Something isn't working labels Oct 9, 2026
@ogabrielluiz
ogabrielluiz force-pushed the fix/migration-page-rehearsal-findings branch from 66a9f06 to 5923f40 Compare October 9, 2026 17:22
@github-actions github-actions Bot added bug Something isn't working and removed bug Something isn't working labels Oct 9, 2026
@ogabrielluiz
ogabrielluiz force-pushed the fix/migration-page-rehearsal-findings branch from 5923f40 to 84c0226 Compare October 9, 2026 18:08
@github-actions github-actions Bot added bug Something isn't working and removed bug Something isn't working labels Oct 9, 2026
@ogabrielluiz
ogabrielluiz force-pushed the fix/migration-page-rehearsal-findings branch from 84c0226 to 46923fc Compare October 9, 2026 18:38
@github-actions github-actions Bot added bug Something isn't working and removed bug Something isn't working labels Oct 9, 2026
@ogabrielluiz
ogabrielluiz force-pushed the fix/migration-page-rehearsal-findings branch from 46923fc to e32b268 Compare October 9, 2026 18:46
@github-actions github-actions Bot removed the bug Something isn't working label Oct 9, 2026
ogabrielluiz and others added 3 commits October 9, 2026 19:39
A rehearsal of the whole move on real instances found these.

The document itself could scroll on the migration page and hide the top
bar. Each locked step holds a line that only a screen reader hears. It
is positioned out of the flow, and nothing between it and the document
was positioned, so it was placed against the document and made it
taller than the window. The page's root is positioned now.

The knowledge bases test of "Where your data goes" has two more reasons
with a line each: the server has no pgvector package, and an instance
that already runs on PostgreSQL has no PGVECTOR_CONNECTION_STRING. On
such an instance the note at the test says the knowledge bases go to
the store that variable names, where it said the new instance's
database, and the refusal under it is what to do. The missing variable
also stops "Copy knowledge bases" and refuses its start. No note stands
there, so that line says why as well, and it ends with the copy.

A pause that is refused because changes under way had not finished
says to try again in a moment, and trying again does not ask twice.

The walks cover the document that stays put, a backup confirmed with no
place named, which the browser's own message stops, and a destination
step on an instance that has knowledge bases.
… again

A copy that ran keeps its place when a step before it opens again, for
example when the check fails again during the pause. The server refuses
to start it then. The page still offered "Copy again" and answered the
refusal with the line it has for a failure it cannot name.

A copy step now offers no start, real or test, while a step before it
is neither done nor skipped. It says "Finish the steps above first."
where the buttons were, and what the copy did stays on show. A tab that
has not read the new state yet can still send a start. The server
answers that it is locked, and the step says the same line.

The line under an option the admin ticked said "Copy again for this to
apply." After a test run no copy exists yet, so it now says that the
choice applies to the next copy, in the 8 locales.
When a read of the state reopens a step above a copy, the start buttons
go away. Focus then fell to the document body and the line in their place
was not announced. That line is now a status, and it takes the focus when
the buttons it replaces held it.

Also correct the comments on the knowledge bases line for a missing
PGVECTOR_CONNECTION_STRING: the PostgreSQL note always stands above it,
and the test now asserts that note.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working lgtm This PR has been approved by a maintainer

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants