← All posts shopify theme check --path vs Positional Arguments: The Definitive Syntax Guide

shopify theme check --path vs Positional Arguments: The Definitive Syntax Guide

Learn exactly why shopify theme check --path is the only valid way to scope a lint run and why positional file arguments silently fail in Shopify CLI.

Use shopify theme check --path ./your-theme to scope a lint run to a directory. There are no positional arguments in the current Shopify CLI: shopify theme check ./sections/header.liquid is invalid syntax and the CLI will not lint that file. The --path flag is the one and only mechanism the tool exposes for directory scoping.

Key takeaways

  • --path scopes the run to a directory; it does not accept a single file path.
  • Positional arguments (e.g. shopify theme check ./sections/header.liquid) are not supported and produce no useful output.
  • Omitting --path defaults to the current working directory.
  • The SHOPIFY_FLAG_PATH env var is the CI equivalent of --path.
  • Since CLI 4.0 (released May 2026), Node 22.12+ and Git 2.28+ are required.

The core confusion: why the command looks like it should accept a file

Every other popular linter (ESLint, Stylelint, RuboCop) accepts a positional file or glob:

eslint src/main.js          # valid
stylelint "src/**/*.css"    # valid
shopify theme check ./sections/header.liquid  # INVALID

Shopify Theme Check does not follow that convention. The CLI's theme check command accepts no positional arguments at all. If you pass a path as a positional argument, the CLI does not error loudly; it simply ignores it and lints the current working directory instead. That silent fallback is what makes this bug hard to find.

This matters more than it sounds. Developers debugging a single noisy file often run shopify theme check ./snippets/icon-sprite.liquid, see a full-theme report, assume the check passed for that file, and ship. The check never ran in isolation.

The --path flag: what it actually does

The --path flag tells Theme Check which directory to use as the theme root. It defaults to the current working directory when omitted.

# Lint the theme in the current directory (implicit)
shopify theme check

# Lint a theme in a subdirectory
shopify theme check --path ./my-theme

# Lint a theme in a build output folder
shopify theme check --path ./dist

Important: --path must point at a directory that contains the standard Shopify theme folder structure (templates/, sections/, snippets/, etc.). Passing it a single file path is not valid either.

The environment variable equivalent is SHOPIFY_FLAG_PATH, which follows the standard SHOPIFY_FLAG_* naming pattern that almost every other flag uses in the current CLI.

Complete flag reference for shopify theme check

Here are all the flags you will actually use, with their purposes:

FlagShortWhat it doesDefault
--path(none)Sets the theme root directory to lintCurrent working directory
--fail-level(none)Exit code 1 when issues at this severity or above are founderror
--auto-correct-aAutomatically fixes offenses that support correctionOff
--config-COverrides .theme-check.yml with a named config preset.theme-check.yml in root
--output-oOutput format: text or jsontext
--init(none)Generates a starter .theme-check.yml in the theme rootN/A
--no-color(none)Disables ANSI color codes (useful in CI logs)Color on
--verbose(none)Increases output verbosityOff

The --fail-level flag is especially important for CI pipelines. By default, Theme Check only exits with code 1 on error-severity issues. If you also want to block on warnings, you must be explicit:

shopify theme check --path ./theme --fail-level warning

Why you cannot lint a single file with the CLI

Theme Check is designed as a whole-theme linter, not a file linter. Many checks depend on cross-file context:

  • UnusedSnippet needs to know every file that calls {% render %}.
  • TranslationKeyExists needs to read locale files alongside your Liquid.
  • MissingTemplate needs the full templates/ directory to check references.

Running a single-file check would produce meaningless results for those cross-file rules. That is a deliberate design decision, not an oversight. If you want per-file feedback as you type, use the Shopify Liquid VS Code extension, which runs Theme Check's Language Server Protocol (LSP) in real time.

This was a significant leap forward when Theme Check 2.0 was released, unifying the linter and adding LSP features like hover docs and code completion for settings, translations, HTML, and Liquid directly inside editors.

What changed in CLI 4.0 (May 2026)

If you are running older tutorials, be aware that Shopify CLI 4.0, released in May 2026, introduced several changes that affect how theme check runs:

  • Auto-upgrade by default: The CLI now self-upgrades via your package manager. Auto-upgrade is skipped in CI environments and on major version bumps.
  • Node 22.12+ and Git 2.28+ required. Earlier Node versions will throw errors on install.
  • theme init now clones Skeleton, not Dawn. This affects which theme structure is scaffolded for new builds.
  • No interactive login commands: There is no shopify login or shopify whoami on the current CLI. Authentication is token-based.

For CI/CD pipelines, the documented non-interactive pattern is still a linter gate followed by a push:

shopify theme check --path ./theme --fail-level error
shopify theme push --json --theme staging

Scoping Theme Check in CI: the right way

Here is a minimal but production-ready GitHub Actions step:

name: Theme Check
on: [push, pull_request]
jobs:
  theme-check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v4
        with:
          node-version: '22'
      - name: Install Shopify CLI
        run: npm install -g @shopify/cli @shopify/theme
      - name: Run Theme Check
        run: shopify theme check --path . --fail-level warning
        env:
          SHOPIFY_FLAG_STORE: ${{ secrets.SHOPIFY_STORE }}

If you use Shopify's official theme-check-action@v2, the path equivalent is the theme_root input, not a positional argument:

- uses: Shopify/theme-check-action@v2
  with:
    theme_root: './dist'
    flags: '--fail-level warning'

The theme_root input maps to --path internally. The flags input lets you pass any additional flags, including --fail-level.

Three approaches compared

ApproachValid syntaxWhen to useTrade-off
shopify theme checkYesLocal dev, theme is in cwdNo path scoping needed
shopify theme check --path ./distYesBuild-output or monorepo structureRequires correct dir layout
shopify theme check ./sections/header.liquidNoNeverSilently ignored; lints cwd instead
shopify theme check --path ./sections/header.liquidNoNeverNot a theme root directory
Shopify/theme-check-action@v2 with theme_rootYesGitHub Actions CIOfficial action; handles auth edge cases

Silencing false positives without disabling entire checks

If Theme Check flags valid code (a custom Liquid filter, a third-party tag), use inline suppression comments rather than disabling the whole check globally:

{% # theme-check-disable LiquidTag %}
{{ product.title | my_custom_filter }}
{% # theme-check-enable LiquidTag %}

For persistent false positives across multiple files, the ignore key in .theme-check.yml is cleaner:

LiquidTag:
  enabled: true
  ignore:
    - snippets/vendor-component.liquid

You can generate a starter config at any time with shopify theme check --init, which writes a .theme-check.yml pre-loaded with Shopify's recommended settings.

The env var precedence chain

Precedence in the current CLI is: flag > env var > shopify.theme.toml. A --path flag on the command line overrides SHOPIFY_FLAG_PATH in the environment, which overrides any path set in the toml file. A stray inline flag in a script will silently override a CI env var, which is a common source of "it works locally but not in CI" confusion.

If your CI step is still prompting interactively, add SHOPIFY_FLAG_FORCE=1 to suppress confirmation prompts.

For a deeper look at how a professional theme development workflow fits together, see my guide on Shopify theme development Liquid best practices. If you are optimizing your theme's front-end performance alongside linting, Shopify speed optimization covers the complementary runtime side.

shopifytheme developmentshopify cliliquidci/cd

Frequently asked questions

Can I run shopify theme check on a single Liquid file?

No. The current Shopify CLI does not accept positional file arguments. Passing a file path as a positional argument is silently ignored and the tool lints the current working directory instead. For per-file feedback in real time, use the Shopify Liquid VS Code extension, which runs Theme Check's LSP server as you type.

What is the difference between --path and a positional argument in shopify theme check?

The --path flag is a named flag that sets the theme root directory for the lint run. A positional argument would be a bare path typed after the command with no flag name, like 'shopify theme check ./my-theme'. Shopify CLI does not support positional arguments for theme check, so only --path works.

How do I scope shopify theme check to a subfolder in a monorepo?

Use the --path flag pointing to the subdirectory that contains the standard Shopify theme folder structure (templates/, sections/, snippets/). For example: 'shopify theme check --path ./packages/storefront-theme'. The subfolder must be a complete theme root, not a partial directory like sections/ alone.