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.