## TL;DR

Run `flyway baseline` to mark the current schema as your starting point, then `flyway migrate` works normally. Flyway stops because it cannot tell which migrations already ran on a database it did not create, so it refuses to guess rather than risk double-applying DDL.

```text
Found non-empty schema without schema history table
```

## Steps

1. Confirm the schema really has no history table. List the tables in the database with your normal DB client or admin tool.
   Expected: you see application tables but no `flyway_schema_history` table.

2. Decide baseline vs repair. A missing history table means baseline is the right call. (If the history table exists but has failed rows, use `flyway repair` instead - that is a different fix.)
   Expected: you have made an explicit choice and can say why.

3. Run the baseline with your connection configured (database URL, user, and database password set in your Flyway configuration per your setup):
   ```
   flyway baseline -baselineVersion=1 -baselineDescription="initial production state"
   ```
   Expected: `Successfully baselined schema with version: 1`.

4. Run `flyway migrate`.
   Expected: `Schema is up to date`, or your pending migrations apply cleanly, and `flyway_schema_history` now contains the baseline row.

5. For fresh environments going forward, turn on the baseline-on-migrate setting in your Flyway configuration so empty databases self-baseline instead of erroring.
   Expected: `flyway migrate` on a brand-new database baselines automatically, then migrates.

## Use this when

- Flyway fails on a database that already has tables but no `flyway_schema_history` table
- You are taking over a legacy database and starting Flyway versioning from its current state
- The same migration set works on fresh databases but fails on the long-lived one
- The error message suggests baseline or repair and the history table is absent

## Not for this skill when

- The `flyway_schema_history` table EXISTS but has failed or out-of-order rows (use `flyway repair`, not baseline)
- Checksums mismatch on existing history rows (checksum repair, different fix)
- You actually want Flyway to rebuild the schema from scratch (drop the tables first, then migrate - do not baseline)
- The schema is empty (nothing to baseline; just migrate)

## Variant phrasings

- flyway "Found non-empty schema(s)" without schema history table
- flyway migrate fails on existing database with no history table
- how to baseline flyway on a production database
- flyway baseline vs repair which one to use

## Why it happens

Flyway tracks applied migrations in `flyway_schema_history`. On a database it did not create, that table is absent, so Flyway cannot distinguish "migrations 1-40 were already applied by hand" from "brand-new database that needs everything". Rather than guess and risk double-applying DDL, it refuses. Baseline writes a single marker row saying "everything up to version N is already here", and future migrations apply on top of it.

## Edge cases

- Set the baseline version to match the newest migration your schema already reflects. Migrations at or below the baseline version are skipped; set it too low and old files re-run.
- Baseline does not validate that the schema actually matches the claimed version. It trusts you, so verify by hand first.
- If some migrations were applied by hand and others were not, baseline only up to the fully-applied ones and handle the rest individually.
- Document the baseline version where the team can find it so every environment agrees.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_b0C4uT8IlXpg-e6Pov5Hhg
