I upgraded a client’s CI image to the latest @shopify/cli in May 2026 and the theme lint step went green on a theme it had been catching errors in for months. Not green because the errors were fixed. Green because the runner was scanning an empty current directory. The old command, theme-check ./theme, still exited zero, so nobody noticed until a deprecated {% include %} shipped to a Factory Direct Blinds staging build.
TL;DR: Shopify CLI 3.0 removed the positional path argument. The folder you want to lint goes in the --path flag now, not after the command. Run shopify theme check --path ./your-theme. With no --path, it lints the current working directory. The bare positional form (shopify theme check ./your-theme) is leftover 2.0 and standalone-gem syntax, and it does not target that folder.
Why this matters for your store:
- A theme check step that silently scans the wrong directory passes every build while real offenses ship. That is worse than no lint, because the green check buys false confidence.
- Most tutorials and Stack Overflow answers still show the positional path from the old Ruby
theme-checkgem. Copy one into a 3.0 pipeline and it runs against nothing. - The
--pathand--configflags solve different problems. Confusing the theme directory with the config file is the quiet second cause of theme check commands that look right and do nothing.
The correct syntax
The integrated command is shopify theme check [flags]. The directory to scan is a flag, not a trailing word.
# Lint the current working directory (most common, run from theme root)
shopify theme check
# Lint a specific directory
shopify theme check --path ./themes/dawn
# Absolute paths work too
shopify theme check --path /Users/you/work/store-theme
The --path flag is documented as “the path where you want to run the command,” and it defaults to the current working directory. That default is why running it from inside your theme root with no flag is the normal case, and why a misconfigured CI runner that starts one directory too high lints nothing and still exits clean.
What changed between CLI 2.0 and 3.0
This is the whole source of the confusion. In Shopify CLI 2.0 you set the directory with a positional argument. The official 3.0 migration guide states it plainly:
Specify the directory that you want to use using the
[root]positional argument -> Specify the directory that you want to use using the--pathflag.
So the two forms map like this:
# Shopify CLI 2.0 (and the old standalone theme-check gem)
theme-check ./theme
# Shopify CLI 3.0 and later
shopify theme check --path ./theme
Shopify made the change to keep one path convention across theme dev, theme push, theme pull, and theme check, all of which now take --path. The cost is that a decade of blog posts showing the positional form are now wrong, and they fail silently rather than loudly, which is the trap.
Do not confuse --path with --config
The two flags that get swapped are --path (which theme to scan) and -C / --config (which .theme-check.yml to apply). They are independent.
# Scan ./theme, but apply a stricter CI config from a different folder
shopify theme check --path ./theme -C ./ci/.theme-check.yml
--config overrides the .theme-check.yml in the scanned directory if one is present. It supports the bundled presets too, for example theme-check:recommended and theme-check:all. Use it when your CI rules are stricter than what you keep in the repo for local development.
The pattern that fails a pipeline correctly
A lint step is only useful if it can fail the build. Theme Check is a static analyzer, so it needs no authenticated store, which makes it ideal for CI.
shopify theme check --path . --fail-level error --output json > theme-check.json
--path .scans the checked-out repo root. Be explicit here even though it is the default, so the command does not depend on which directory the runner happens to start in. That single habit would have caught the silent-green failure above.--fail-level errorsets the minimum severity that returns a non-zero exit code. The options areerror,suggestion, andstyle. Start aterrorso the pipeline fails on real breakage without drowning in style noise, then tighten over time.--output jsonwrites a machine-readable report you can attach to the build artifact or parse for annotations. The default istext.
Two more flags worth knowing: -a / --auto-correct fixes the offenses that are safely correctable, and --list prints the active checks so you can confirm your config loaded. For the deprecated tags Theme Check flags most often, the {% include %} to {% render %} swap is the big one, covered in my Liquid render tag reference.
The takeaway:
- The theme directory goes in
--path, never as a positional word after the command.shopify theme check --path ./theme. - The bare positional form is CLI 2.0 and old-gem syntax. It does not error, it just lints the wrong place, which is why it is dangerous.
--pathis the theme to scan,-C/--configis the rules to apply. Keep them straight.- In CI, always pass
--path .explicitly plus--fail-level error, so a runner that starts in the wrong directory cannot pass a build it should fail.
For the wider set of Liquid mistakes Theme Check surfaces and how to fix each one, see my Shopify Liquid best practices guide.