Skip to main content

LINT.NO_MIGRATIONS_READ — the run judged no migration at all

  • Category: safety
  • Level: 0
  • Stability: stable
  • Suites: lint

The run completed, had rules, and had nothing to apply them to: zero migrations were judged.

Without this finding the outcome is indistinguishable from a clean one. The summary does say over 0 migrations, and that line sits beside twenty others in a pipeline log while the exit code — the thing an automation actually reads — says the same as a run that examined three hundred files.

The cause is the ordinary case, not an edge case

sqlens:lint --path=… lints the pending migrations of a connection. Pending is a fact about the database, not about the directory, so nothing is pending as soon as they have all run:

  • on a developer machine, from the first php artisan migrate onwards;
  • in a pipeline that lints after its migration step — which is where the check is most naturally hung, because that is where a database exists.

So the place the check is most likely to live is the place it can see the least. A directory holding fifty-six migrations, all applied, produces exactly zero subjects.

Not a rule, and it says so

This is a runner notice: no rule produced it, and no rule could, because it states something about the run as a whole rather than about a statement. It carries an id, a message prefix and this documentation URL exactly like a rule's finding, because a reader should not have to know the difference to act on it.

It is derived from the count of judged migrations rather than from a list of known causes, so a cause nobody has enumerated still reports.

How it differs from the other empty-run findings

FindingWhat it means
LINT.NO_MIGRATIONS_READThe pending set resolved, and it is empty. Nothing was judged.
LINT.SKIPPED.EMPTY_MIGRATION_PATHNo migration path holds a file at all.
LINT.SKIPPED.NO_MIGRATION_TABLEThe connection has no migration table, so pending is unknowable.
LINT.NO_ACTIVE_RULESThere were migrations; the category and level scope admitted no rule.

The first two look alike from the outside and send you to different places — one to your database state, the other to your directory.

What to do

  • Lint before the migration step. In a pipeline that is usually one line's difference and restores the whole check.
  • Name the files instead of the connection. --file is the database-free path and judges a file regardless of whether it has run.
  • Accept it deliberately. It suppresses like any other finding — a baseline entry or an sqlens.ignore rule — and because it is undetermined the suppression only bites when sqlens.suppression.allow_undetermined also lists no_migrations_read. Two switches, on purpose: hiding a result the run could not produce is a decision rather than a filter setting. Doing it in the job that is supposed to be your gate puts the silence back.

It reaches the exit code under strict mode

Like every undetermined result, this one moves the exit code when strict_undetermined is on — which --profile=ci sets for you. Without it the run still reports the finding and still exits clean, because a developer's local run after migrate should not fail.