Finds the .gitlab-ci.yml keywords GitLab retired, plus the GitHub Actions syntax an AI assistant pastes in, before the job fails on your runner. Runs entirely in your browser — nothing is uploaded.
Same engine as the VS Code extension, byte for byte.
Free for the file open in your editor - no key, no limit. The workspace sweep and the report ask for a key.
VS Code MarketplaceOpen VSX (Cursor, VSCodium)npmMCP server (npx)Docker Hubext install ReadyStack.gitlab-ci-break-lint npx @readystack/gitlab-ci-break-lint <file> npx @readystack/gitlab-ci-break-lint --mcp
Team? One key for every ReadyStack linter, 5 seats, $149 once
Scan every pipeline file in the repository in one pass and export a dated Markdown upgrade report (file, line, keyword, replacement) to attach to the change ticket.
One payment, one licence key for this tool. The key is shown right after payment.
A freelance DevOps engineer's hour runs about $100, and reading a repository's pipelines by hand against a removals list is most of a morning.
Buy the full version — $29· ReadyStack
Real numbers from this tool, line by line.

Six retired keywords in a 31-line .gitlab-ci.yml — that is what a DevOps engineer on self-managed GitLab gets back from a pipeline file an AI assistant drafted for them. The file is not broken. It runs green today. It stops running the day the instance crosses a major upgrade.
That gap is the whole problem. GitLab removes CI keywords only in major releases, so a retired keyword lives in your repository for months in perfect health. Your runner accepts it. GitLab's own CI Lint accepts it, because CI Lint validates the file against the version your instance is running right now — the version where the keyword still works. Nothing in the loop is looking at the version you are about to move to.
Here is the bundled dirty fixture, 31 lines, and the six lines that will not survive:
| Line in the file | What replaces it |
|---|---|
types: | stages: |
type: build | stage: build |
$CI_BUILD_REF | $CI_COMMIT_SHA |
reports: cobertura: | reports: coverage_report: |
$CI_JOB_JWT | id_tokens: VAULT_ID_TOKEN: |
only: - main | rules: - if: $CI_COMMIT_BRANCH |
Six findings, six line numbers, six replacement lines. The same pipeline rewritten the way GitLab accepts it returns nothing.
Two places, and neither of them is carelessness.
The first is age. A pipeline written years ago picked up types: and CI_BUILD_REF when those were the documented keywords. Nobody rewrites a working pipeline. It gets copied into the next repository instead, and the removal notice lands in a release post nobody reads, because nothing was failing.
The second is newer. Ask an assistant for "a CI pipeline that builds and tests this repo" and you get whichever CI syntax it saw most, usually GitHub Actions. That is how runs-on:, steps:, - uses: and ${{ }} expressions end up in a file called .gitlab-ci.yml. GitLab does not reject the one bad line — it rejects the whole file, so the pipeline never starts.
Sixteen rules, in three groups.
Keywords GitLab retired. types: and type:, the whole CI_BUILD_* variable family, artifacts:reports:cobertura, CI_JOB_JWT and its _V1 / _V2 siblings, and only: / except:. Each reports with its line number and replacement: artifacts:reports:cobertura becomes artifacts:reports:coverage_report with coverage_format: cobertura.
GitHub Actions syntax in a GitLab file. runs-on:, steps:, - uses:, ${{ ... }}, and a top-level on: or jobs: mapping.
Job wiring GitLab will not accept. rules: and only: in the same job, a stage: that is missing from stages:, a needs: or extends: that points at a job or key which does not exist, start_in: without when: delayed, parallel: outside the 2–200 range, and a job with no script:, trigger: or extends:.
Free, in the editor or in the browser, with no key and no account: lint the pipeline file you have open. All sixteen rules, every line number, every replacement line. When the report is empty, that file is done — the whole job for one file, not a sample.
The licence key changes the scope, not the checks. It scans every pipeline file in the repository in one pass and exports a dated Markdown upgrade report — file, line, keyword, replacement — as a single table you attach to the change ticket, so the upgrade window has an artefact instead of a promise.
A freelance DevOps engineer's hour runs about $100, and reading one repository's pipelines by hand against a removals list is most of a morning.
It reads a .gitlab-ci.yml as text and reports the lines GitLab no longer accepts, or will stop accepting at the next major release. Each finding gives the line number, the retired keyword or invalid wiring, and the replacement line. On the bundled 31-line dirty fixture it returns six findings; the clean rewrite returns none.
DevOps and platform engineers who own .gitlab-ci.yml files, especially on self-managed GitLab where the instance upgrade date is yours to schedule. It also helps anyone reviewing a pipeline an AI assistant drafted, because assistants mix GitHub Actions keys such as runs-on: and steps: into GitLab files.
GitLab's CI Lint validates the file against the version your instance runs right now. That is exactly the version where the retired keywords still work, so it returns a pass. The breakage appears on the first push after the upgrade, when those keywords are gone and the job that used them fails.
Free: lint the pipeline file you have open, with all 16 rules and every replacement line. The open file is finished when the report is empty. Paid: scan every pipeline file in the repository in one pass and export a dated Markdown upgrade report to attach to the change ticket.
A freelance DevOps engineer's hour runs about $100. Reading a repository's pipeline files line by line against a keyword removals list, then writing the replacements into a ticket, is most of a morning for one repository, and it has to be redone at every major release.
A general AI chat answers from training data with a cutoff date, cannot read your repository and names no rule version. GitLab CI Break Lint checks the file you open against 16 rules from a rule set dated 2026-09-20, and points at the exact line with the fix. For a filing, an audit or a client you need that dated result on your own files.
One question, answered by the person who built it. Your email only if you want the answer sent.
Paste this code into your page. It runs in your visitor’s browser and stays up to date. Nothing your visitors type is stored.
For businesses: your name and logo instead of ours, and each visitor’s result + e-mail in your inbox (only when they tick consent) — Pro from $19/month. See Pro →