CircleCI は 2026 年 9 月 21 日に、config のコンパイル方法に関する破壊的変更を予定しています。
そのうちの一つが正規表現エンジンの更新で、when: matches: の pattern: に書いた一部の正規表現が、これまで通っていたのにコンパイルエラーになります。
この記事では、when: matches: pattern: で使えなくなる機能を circleci config validate --next で事前に洗い出し、when: の範囲に閉じた形へ書き換える手順を紹介します。
本記事の検証は CircleCI CLI 0.1.38646+f96353c6(Homebrew 版)で、2026 年 6 月 23 日に実施しました。公開・参照時点で 公式 Discuss の最新情報もご確認ください。
1. この変更で何が起きるか
正規表現エンジンの更新により、when: matches: の pattern: に書いた正規表現のうち、次の機能を使ったものがコンパイルエラーになります。
- 否定先読み(negative lookahead、
(?!...)) - 否定後読み(negative lookbehind、
(?<!...)) - 絶対最大量指定子(possessive quantifier、
?+*+++など) - 後方参照(backreference、
\1など)
該当すると config のコンパイルが失敗し、パイプラインが実行されません。
2. 自分が影響を受けるか確認する
書き換えの前に、まず自分の config が影響を受けるかを確認します。確認手段は 2 つあり、どちらも「新しいコンパイラで通るか」を先取りして試すものです。
CircleCI CLIで確認する
一つ目は CLI です。circleci config validate に --next フラグを付けると、次世代コンパイラで検証します。
circleci config validate .circleci/config.yml --next
--next を付けない通常の検証(現行コンパイラ)では通るのに、--next を付けると失敗する場合、その差分が今回の破壊的変更で壊れる箇所です。つまり --next あり / なしの両方を実行し、結果が変わる config が対象になります。
CircleCI ダッシュボードから確認する
二つ目は config editorです。ジョブ実行結果詳細ページにある、[Config]ボタンをクリックすると開くUIで、CircleCIのCI YAMLを確認・編集することができます。
編集画面下部の検証バーにある「Use next config compiler」トグルを有効にすると、CLI の --next と同じ次世代コンパイラで検証され、結果が UI 上に表示されます。
3. 失効する 4 機能と書き換え
ここからは 4 機能それぞれについて、変更前の config → --next でのエラー → 書き換え後の config → 再検証をそれぞれ紹介します。
3-1. 否定先読み(negative lookahead)
ブランチ名が main で始まらない場合に step を実行する例です。
# 変更前(--next でコンパイルエラー)
version: 2.1
jobs:
build:
docker:
- image: cimg/base:current
steps:
- checkout
- when:
condition:
matches:
pattern: "^(?!main).*$"
value: << pipeline.git.branch >>
steps:
- run: echo "not main"
workflows:
test:
jobs:
- build
この config を --next で検証すると、否定先読みが受理されずコンパイルエラーになります。
$ circleci config validate .circleci/config.yml --next
Error: config compilation contains errors: config compilation contains errors:
- Error calling workflow: 'test'
- Error calling job: 'build'
- Invalid regular expression: ^(?!main).*$: Invalid pattern.
否定先読み (?!main) は「main で始まらない」という除外条件です。これを正規表現の内部で表現するのをやめ、not: matches: で除外を構造として外に出します。
# 変更後(--next で pass)
version: 2.1
jobs:
build:
docker:
- image: cimg/base:current
steps:
- checkout
- when:
condition:
not:
matches:
pattern: "^main.*$"
value: << pipeline.git.branch >>
steps:
- run: echo "not main"
workflows:
test:
jobs:
- build
not: matches: pattern: "^main$"(完全一致の否定)は、元の ^(?!main).*$ と等価ではありません。
matches は完全一致で評価されるため、^main$ の否定は「文字列がちょうど main の場合だけ除外」になり、maintenance や main-backup のような main で始まる別ブランチが除外されずに通ってしまいます。元の否定先読みは「main で始まる」すべてを除外するので、前方一致で除外する ^main.*$ を否定するのが正しい書き換えです。
書き換え後、再度 --next で検証して pass することを確認します。
$ circleci config validate .circleci/config.yml --next
Config file at .circleci/config.yml is valid.
あわせて、いくつかのブランチ名で変更前と分岐結果が一致することを確認しましょう。
| ブランチ名 | 変更前 | 変更後 |
|---|---|---|
| main | 実行しない | 実行しない |
| maintenance | 実行しない | 実行しない |
| develop | 実行する | 実行する |
3-2. 否定後読み(negative lookbehind)
release- で始まり、かつ -wip で終わらないブランチの場合に step を実行する例です。否定後読み (?<!...) も同様に受理されなくなります。後読みで表現していた除外条件は、and: で「マッチする条件」と「マッチしない条件(not:)」に分割します。
# 変更前(--next でコンパイルエラー)
condition:
matches:
pattern: "^release-.*(?<!-wip)$"
value: << pipeline.git.branch >>
--next での検証では否定後読みが弾かれます。
$ circleci config validate .circleci/config.yml --next
Error: config compilation contains errors: config compilation contains errors:
- Error calling workflow: 'test'
- Error calling job: 'build'
- Invalid regular expression: ^release-.*(?<!-wip)$: Invalid pattern.
「release- で始まり、かつ -wip で終わらない」を、後読みを使わず 2 つの条件の and: に分けます。
# 変更後(--next で pass)
condition:
and:
- matches:
pattern: "^release-.*$"
value: << pipeline.git.branch >>
- not:
matches:
pattern: "^.*-wip$"
value: << pipeline.git.branch >>
肯定条件を matches: で、除外条件を not: matches: で書き、and: でまとめる形です。書き換え後の --next は pass し、release-1.0 は実行・release-1.0-wip は実行しない・develop は実行しない、と変更前の分岐結果に一致します。
3-3. 絶対最大量指定子(possessive quantifier)
タグが v + 数字(例: v1、v12)の形式の場合に step を実行する例です。?+ *+ ++ のような、量指定子の後ろに + を付けた絶対最大量指定子も使えなくなります。多くの場合バックトラック抑制のために付けられているもので、条件判定としての意味を変えずに末尾の + を外せます。
# 変更前(--next でコンパイルエラー)
condition:
matches:
pattern: "^v\\d++$"
value: << pipeline.git.tag >>
--next では絶対最大量指定子が受理されません。
$ circleci config validate .circleci/config.yml --next
Error: config compilation contains errors: config compilation contains errors:
- Error calling workflow: 'test'
- Error calling job: 'build'
- Invalid regular expression: ^v\d++$: Invalid pattern.
末尾の余分な + を外し、通常の量指定子に戻します。
# 変更後(--next で pass)
condition:
matches:
pattern: "^v\\d+$"
value: << pipeline.git.tag >>
\d++ を \d+ にするだけで、マッチする文字列の集合は変わりません(v1・v12 は実行、v1.0 は実行しない、で変更前と一致します)。書き換え後に --next で pass を確認します。
3-4. 後方参照(backreference)
ブランチ名が「同じ語がハイフンで 2 回繰り返される」形式(例: foo-foo)の場合に step を実行する例です。後方参照 \1 は「前半でマッチした文字列と同じものが再度現れる」ことを表しますが、これは新エンジンでは表現できません。
# 変更前(--next でコンパイルエラー)
condition:
matches:
pattern: "^(\\w+)-\\1$"
value: << pipeline.git.branch >>
--next では後方参照が弾かれます。
$ circleci config validate .circleci/config.yml --next
Error: config compilation contains errors: config compilation contains errors:
- Error calling workflow: 'test'
- Error calling job: 'build'
- Invalid regular expression: ^(\w+)-\1$: Invalid pattern.
後方参照を外し、緩い正規表現に置き換えて --next を通します。
# 変更後(--next で pass)
condition:
matches:
pattern: "^\\w+-\\w+$"
value: << pipeline.git.branch >>
この書き換えはコンパイルを通すための近似であり、厳密には等価ではありません。後方参照を外したことで判定が緩み、元は弾いていた文字列も通るようになります。
| ブランチ名 | 変更前 | 変更後 |
|---|---|---|
| foo-foo | 実行する | 実行する |
| foo-bar | 実行しない | 実行する(緩和) |
| release-1.0 | 実行しない | 実行する(- を含む語で誤マッチ) |
厳密な一致判定が必要な場合は、取り得る値を or: で列挙するか、判定自体を config の外(ジョブ内のスクリプト)に出すことを検討してください。
4. 書き換え後に再検証する
すべての書き換えが終わったら、config 全体を --next で検証し、pass することを確認します。
circleci config validate .circleci/config.yml --next
正規表現の書き換えは、コンパイルが通ること(構文)と、意図どおりの分岐になること(意味)の 2 つを満たす必要があります。特に 3-1 の否定先読みと 3-4 の後方参照は、書き換えでマッチする集合が変わりやすいので、代表的な入力値で分岐結果が変わっていないかを確認してください。
5. まとめ
- 2026 年 9 月 21 日の正規表現エンジン更新で、
when: matches: pattern:に書いた否定先読み・否定後読み・絶対最大量指定子・後方参照はコンパイルエラーになります - 影響の有無は
circleci config validate --next(または config editor の「config next」トグル)で、--nextあり / なしの差分として確認できます - 書き換えは
branches: ignore:へ逃がさず、when:のnot:/and:の範囲に閉じて移行できます。ただし完全一致の否定(^main$)と前方一致の否定(^main.*$)を取り違えないよう注意してください。後方参照だけは近似(緩和)になるため、緩めた結果を必ず確認してください
本記事は 2026 年 7 月 23 日時点の情報にもとづきます。対応前に 公式 Discuss(single source of truth) の最新値を確認してください。

