パッケージの衝突

! LaTeX Error: Option clash for package inputenc は「同じパッケージを違うオプションで 2 回読み込んだ」と説明されるのが普通ですが、それは正確ではありません。実際に latex.ltx が行っている判定は部分集合の検査です——2 回目の \usepackage が要求したオプションが、1 回目に与えられたオプションの中にすべて含まれていれば通り、一つでも新顔があれば衝突する。だから \usepackage[a,b]{X} のあとの \usepackage[a]{X} は無事で、逆順は落ちます。さらに厄介なことに、この検査をまるごと素通りするパッケージがあり、xcolor はその代表です。このページは、その規則の正体、\PassOptionsToPackage を書くべき正確な位置、hyperref を最後に置く理由、そして TeX Live 2024 でいまも本当に共存できない組み合わせを扱います。

衝突する条件は「違うオプション」ではなく「新しいオプション」

2 回目の \usepackage は、1 回目に無かったオプションを一つでも要求した瞬間に衝突します。逆に、1 回目のオプションの部分集合であれば——順序が違っても、数が少なくても、空でも——何も起こりません。 これは latex.ltx\@onefilewithoptions@clashchk\@if@ptions を呼び、その中身の \@if@pti@ns が要求オプションを一つずつ \in@ で既存リストと照合しているからです。一つでも見つからなければ第二引数の分岐、つまり \@latex@error{Option clash for …} に落ちます。TeX Live 2024 で 7 通りを実際に走らせた結果が下の表で、規則がそのまま観測できます。

1 回目 → 2 回目のオプション結果(TeX Live 2024 で実測)
[alpha] → [beta]衝突。beta は 1 回目に無かった新顔
[alpha] → [alpha]無事。同じオプションの繰り返しは何も起こさない
[alpha] → []無事。空集合はつねに部分集合なので、素の再読込は安全
[] → [alpha]衝突。これが「クラスや他のパッケージに先を越された」典型パターン
[alpha,beta] → [alpha]無事。少なく要求するのは常に許される
[alpha] → [alpha,beta]衝突。多く要求すると落ちる。1 回目に全部書くのが正解
[beta,alpha] → [alpha,beta]無事。順序は関係なく、集合として比較される

エラーの本文はごく短いのに、.log にはどのオプションで先に読み込まれ、いま何を要求したのかが具体的に書かれています。この 4 行が原因究明の中身そのものなので、端末だけ見て悩まずログを開いてください。もう一つ知っておくと得なのは報告される行番号がずれること。\usepackage は末尾に省略可能な日付引数を取れるため、} の後ろに [ が来るかを覗きに行き、その先読みが次の行まで届きます。3 行目の \usepackage が起こした衝突が l.4 \begin{document} として報告されるのはそのためです。

log
% terminal shows only the first line; the rest is in the .log
./oc1.tex:4: LaTeX Error: Option clash for package inputenc.
l.4 \begin
          {document}
The package inputenc has already been loaded with options:
  [utf8]
There has now been an attempt to load it with options
  [latin1]
Adding the global options:
  utf8,latin1
to your \documentclass declaration may fix this.

なぜ xcolor は衝突しないのか——検査を迂回する 3 つの仕掛け

\usepackage[dvipsnames]{xcolor} のあとに \usepackage[table]{xcolor} と書いても、TeX Live 2024 では何のエラーも出ません。理由は「xcolor が例外的に寛容だから」ではなく、部分集合の検査そのものが呼ばれていないからです。 latex.ltx\@onefilewithoptions は、すでに読み込まれたパッケージに対してまず opt@handler@<パッケージ>.sty が定義されているかを見ます。定義されていなければ \@onefilewithoptions@clashchk——つまり先ほどの部分集合検査——へ、定義されていればそちらへ丸投げして、新しいオプションをそのハンドラに処理させます。そして TeX Live 2024 の xcolor.sty は、オプションを \DeclareKeys で宣言し \ProcessKeyOptions で処理する新しい方式に移行済みで、この \ProcessKeyOptions こそが opt@[email protected] を登録している当人です。実際に \show で覗くと、その中身は \ProcessKeyOptions [xcolor] の一行でした。

latex
% no error on TeX Live 2024: xcolor uses \DeclareKeys + \ProcessKeyOptions
\usepackage[dvipsnames]{xcolor}
\usepackage[table]{xcolor}

% still an error: inputenc uses the classic \DeclareOption mechanism
\usepackage[utf8]{inputenc}
\usepackage[latin1]{inputenc}

% check for yourself which mechanism a package uses
\makeatletter
\expandafter\show\csname opt@[email protected]\endcsname
% -> \opt@[email protected]=\protected\long macro: ->\ProcessKeyOptions [xcolor].
\makeatother

キー値方式への移行はいちばん行儀のよい迂回路ですが、ほかにも 2 通りあります。fontenc.sty は読み込みの最後で [email protected][email protected] を両方 \relax に戻します——\@ifl@aded はまさに ver@… を見て判定しているので、fontenc は自分が読み込まれた事実そのものを消して、次の \usepackage[T2A]{fontenc} を新規の読み込みとして通します。もう一つは caption で、こちらは caption3.sty の中でカーネルの \@onefilewithoptions 自体を差し替え、caption 系のパッケージが再読込されたときはオプションを \captionsetup 相当の処理に流してから、空のオプションで読み込み直します。そのすぐ上に置かれた作者のコメントは、2018 年と 2020 年に LaTeX チームへ正式な仕組みを要望したが断られた、と述べており、この置き換えを自ら「汚いハック」と呼んでいます。エラーが出ないパッケージの裏では、たいていこの 3 つのどれかが起きています。

パッケージ(新オプションで再読込)TeX Live 2024 での結果と理由
xcolor衝突しない。\DeclareKeys\ProcessKeyOptions を使うため検査を通らない
fontenc衝突しない。読込の最後に [email protected] を消して「未読込」に戻る
caption衝突しない。caption3.sty がカーネルの \@onefilewithoptions を置き換えている
inputenc衝突する。古典的な \DeclareOption 方式のまま
geometry衝突する。設定を足したいときは \geometry{…} を使う
hyperref衝突する。設定を足したいときは \hypersetup{…} を使う
babel衝突する。言語を足すときは 1 回の \usepackage にまとめて並べる
amsmath衝突する。fleqnleqno はクラスオプションとして書くのが定石

\PassOptionsToPackage を書く位置——1 回目の読込より前、それだけ

\PassOptionsToPackage{opt}{X} は、X が最初に読み込まれるより前に置かなければ意味がありません。確実なのはファイルの一行目、\documentclass よりも前です。 この命令が行っているのは、[email protected] というオプションリストに opt を書き足すことだけ。それだけで二つの効果が同時に得られます——X が読み込まれる瞬間に opt が渡り、かつ後から来る \usepackage[opt]{X} の部分集合検査も通る。つまり「オプションを効かせる」と「衝突を消す」は別々の対処ではなく、同じ一行の表と裏です。\documentclass より前に書けるのは、\PassOptionsToPackage がフォーマットの段階から定義されていて、\usepackage のようにクラス読込を前提にしていないからです。

document.tex
% correct: the very first line, above \documentclass
\PassOptionsToPackage{table}{xcolor}
\documentclass{article}
\usepackage{tikz}          % pulls xcolor in -- with table already attached
\usepackage[table]{xcolor} % no clash, and \rowcolor works

% WRONG: after xcolor is already loaded. No error is raised, and the
% option is silently never executed.
\documentclass{article}
\usepackage{tikz}
\PassOptionsToPackage{table}{xcolor}
\usepackage[table]{xcolor}

この命令にはひどく静かな失敗の仕方があります。X がすでに読み込まれた\PassOptionsToPackage を書いても、エラーは一切出ません——しかしオプションは実行されません。 検査用のパッケージで実測すると、読込前に置いた場合はオプションのコードが走った証拠が出るのに対し、読込後に置いた場合は衝突が消えるだけで、コードは走らないままでした。エラーが消えたので直ったと思い込むのが、この道具のいちばん危ない使い方です。 もう一つ、エラー本文が勧めてくる \documentclass へのグローバルオプション追加も、そのままでは効きません。\documentclass[beta]{article} を足しても \usepackage[alpha]{X}\usepackage[beta]{X} を残したままでは衝突は再現し、局所オプションを両方とも消して \documentclass[alpha,beta]{article}\usepackage{X} にして初めて通ります。

読み込んだ覚えのないパッケージを突き止める

プリアンブルに \listfiles を一行足して .log の末尾を見れば、実際に読み込まれたファイルが全部並びます。そして「誰が引き込んだか」は、ログの括弧の入れ子が答えます。 ( でファイルを開き ) で閉じるので、xcolor.sty を開く (pgfcore.sty の括弧の内側にあれば、引き込んだのは pgf です。実測すると、素の article は 3 ファイルしか読みませんが、tikz を 1 行足すと 34 ファイルになり、その中に xcolor が含まれます。hyperref は単独で 30 ファイルを連れてきます。xcolor なんて書いていないのに Option clash が出る」の答えは、たいていこの一覧の中にあります。 さらに細かく追うなら -recorder を付けると .fls に開いたファイルが全部記録されます。

log
% the nesting says who pulled xcolor in: pgf did
(.../pgf/basiclayer/pgfcore.sty
(.../pgf/systemlayer/pgfsys.sty
...
)) (.../xcolor/xcolor.sty
...
)

% and with \listfiles, the summary table at the end of the .log
 *File List*
 article.cls    2023/05/17 v1.4n Standard LaTeX document class
  xcolor.sty    2022/06/12 v2.14 LaTeX color extensions (UK)
 ***********

読込順の決まり——hyperref を最後に置く理由と、その例外

hyperref を最後近くに置くのは、それが \ref\cite\caption・目次・索引といった多数の仕組みを上書きするからです。上書きは「最終的な定義」に対して行われる必要があるので、後から誰かが同じものを再定義すると、hyperref の細工が消えます。 ただし「最後」ではなく「最後近く」です。hyperref の仕事を前提に作られたパッケージは、当然その後に来なければなりません。代表は bookmarkcleverefhypcapglossaries。中でも cleveref は順序違反を自分で検出してエラーにするので、間違えればすぐわかります(cleveref の読込順は「未定義の参照」のページが詳しく扱っています)。

ここで一つ、はっきり言っておくべきことがあります。「A は B より前」という言い伝えの多くは、TeX Live 2024 では実際には何も起こしません。 試しに floathyperrefgeometryhyperrefalgorithmhyperrefbookmarkhyperrefglossarieshyperref を両方の順序で組んでみましたが、どれもエラーも警告も出ませんでした。パッケージ側の互換処理が年々厚くなった結果です。したがって順序の指定は、そのパッケージ自身のマニュアルに書かれているものだけを守れば十分で、出所のはっきりしない順序の言い伝えに従ってプリアンブルを組み替えるのは、たいてい時間の無駄になります。とはいえ hyperref を末尾近くに置く習慣そのものは、上書きの性質から来る合理的な既定値なので維持してください。

\usepackage\RequirePackage の違い

プリアンブルの中では、この二つは文字どおり同じものです。latex.ltx\documentclass の処理中に \let\usepackage\RequirePackage を実行するので、そこから先は完全に同一の命令になります。違いが出るのは \documentclass より前と、.sty.cls ファイルの中だけ。 その場所では \usepackage! LaTeX Error: \usepackage before \documentclass. を出して止まります——フォーマット段階の \usepackage は、この診断メッセージを出すためだけに定義されているからです。だからパッケージやクラスを自作するときは \RequirePackage を使い、\PassOptionsToPackage と組み合わせて \documentclass より前にオプションを差し込む、という書き方ができます。クラス自身のオプションをそのまま下請けパッケージに渡したいときは \RequirePackageWithOptions が用意されています。

latex
% before \documentclass, only \RequirePackage works
\RequirePackage{fix-cm}
\PassOptionsToPackage{table}{xcolor}
\documentclass{article}

% inside your own mystyle.sty, likewise
\ProvidesPackage{mystyle}[2026/01/01 house style]
\RequirePackage{xcolor}
\RequirePackageWithOptions{geometry}  % forward this package's own options

本当に共存できない組み合わせ——TeX Live 2024 で実際に確かめたもの

オプション以前の問題として、同じ仕組みを二重に定義しあうために共存できない組み合わせがあります。ただしその数は思われているより少なく、しかも症状は「読み込んだ瞬間のエラー」とは限りません。 はっきりエラーで拒否するのは biblatexnatbib の組で、! Package biblatex Error: Incompatible package 'natbib'. と出て止まります(\citet\citep が欲しいだけなら \usepackage[natbib=true]{biblatex} で済みます)。厄介なのは黙って壊れるほうで、subfiguresubcaption を両方読み込んでもエラーは一つも出ません——出るのはずっと後、\begin{subfigure}{0.4\textwidth} を書いた行の ! Missing number, treated as zero. です。古い subfigure が定義する \subfigure 命令に \begin{subfigure} が吸い込まれ、まったく別の解釈をされるからです。

組み合わせTeX Live 2024 で実際に起きること
biblatex + natbib即座にエラーで停止。\usepackage[natbib=true]{biblatex} 一本にまとめる
natbib + biblatex逆順ならエラーにならず、\citeauthor などの再定義が警告として出るだけ
subfigure + subcaption読込は無警告で通る。あとで \begin{subfigure} が壊れ、無関係な顔のエラーが出る
subfig + subcaption読込は通るが subcaption が環境を定義しない。! LaTeX Error: Environment subfigure undefined. になる
caption + subfigureもう衝突しない。.logPackage caption Info: subfigure package is loaded. が残るだけ
cleveref + hyperrefcleveref を先に読むと停止する。hyperrefvarioref の後に置くこと
cite + natbibエラーにはならず、natbibcite を使うなという警告を出す。片方に絞る

この一覧から引き出すべき教訓は、「A と B は非互換」という言い伝えを鵜呑みにせず、手元で 5 行の文書を作って確かめるということです。captionsubfigure の非互換はかつて本当にエラーでしたが、いまはただの Info に格下げされています。逆に subfiguresubcaption は「読み込んでもエラーが出ないから大丈夫」という判断がいちばん危ない例です。症状の出方が「読込時のエラー」から「ずっと後の無関係に見えるエラー」へ移った、というのが TeX Live 2024 における非互換の現在地で、だからこそ \listfiles.log を読む習慣が効いてきます。