対象はpyproject.tomlとuv.lockを使うuvプロジェクトです。
uv sync --frozenが成功しても、現在のpyproject.tomlとuv.lockが整合している証明にはなりません。--frozenは既存のlockをそのまま採用し、現在の設定と合っているかの検査を省くためです。依存追加のlock更新漏れを止めたいならuv sync --locked、環境を同期せずlockだけ確認したいならuv lock --checkを使います。意図した変更ならuv lockで取り込み、--lockedで再確認します。
指定なし・--locked・--frozenの違い
uv公式のLocking and syncingでは、通常のuv syncやuv runは必要に応じてlockと環境を更新すると説明されています。--lockedと--frozenはいずれも自動lock更新を避けますが、古いlockを検査するかどうかが異なります。
| 実行方法 | lockの現在性確認 | lockの自動更新 | 古いlockがあるとき |
|---|---|---|---|
| 指定なし | 行う | 必要なら行う | lockを更新して同期する |
--locked | 行う | 行わない | 更新せずエラーにする |
--frozen | 行わない | 行わない | 既存lockの内容で同期する |
--frozenでも環境同期そのものは行います。uv runで環境同期を省く--no-syncとは別の指定です。また、--frozenでuv.lockが存在しなければエラーになります。詳しいオプション定義はuv CLI Referenceで確認できます。
古いuv.lockを再現する
以下は2026年10月6日に、Windows、uv 0.12.23(46b84fd0b、2026-10-03)、Python 3.13.7、隔離した検証用フォルダーと新しい仮想環境で確認した手順です。実測では--pythonでPython 3.13.7の実行ファイルを指定しました。掲載コマンドはPATH上のuvを使う短縮形です。Python選択をそろえるには、uvのオプションとして--python 3.13を指定します。uv runでは実行対象のpythonより前に置きます。パッケージ取得にはインデックスへのネット接続などが必要です。
1. 空依存のlockと環境を作る
空のフォルダーへ次のpyproject.tomlを保存します。
[project]
name = "uv-lock-demo"
version = "0.1.0"
requires-python = ">=3.13"
dependencies = []uv lockuv sync --locked実測では両方とも終了コード0でした。この時点のlockにはidnaを含めません。
2. pyproject.tomlだけ変更する
[project]内の既存のdependencies行を次の1行へ置き換えます。まだuv lockは実行しません。
dependencies = ["idna==3.10"]--lockedとuv lock --checkで更新漏れを検出する
lockだけを検査する場合は次を実行します。
uv lock --check同期も行う工程では、次を独立して実行します。
uv sync --locked実測ではどちらも終了コード1となり、uv.lockの更新が必要であることを示すエラーになりました。SHA256も不変で、検査のためにlockを書き換えてはいません。エラー文言そのものはuvの版によって変わる可能性があります。失敗時に後続処理を止めるCIやシェルでは、確認目的に応じて別々に試してください。
--frozenは成功しても追加依存を取り込まない
uv sync --frozenuv run --frozen python -c "import importlib.util; print(importlib.util.find_spec('idna') is not None)"新しい専用環境での実測では、同期は終了コード0、確認出力はFalse、lockのSHA256は不変でした。つまり--frozenは古いlockに従って同期し、pyproject.tomlへ追加したidnaをlockにも環境にも取り込みません。確認用のuv runから--frozenを外すと、自動でlockが更新されて比較条件を壊し得るため、再現中は必ず付けます。すでにidnaが存在する別環境でも同じくFalseになるとは限りません。
意図した依存追加をlockへ反映する
uv lockuv sync --lockeduv run --locked python -c "import idna; print(idna.__version__)"実測ではすべて終了コード0となり、uv.lockへidna 3.10が追加され、最後の出力は3.10でした。lockのSHA256も変更されています。pyproject.tomlとuv.lockの差分をレビューし、両方をコミットします。依存追加自体が誤りなら設定側を戻してください。エラーを消すためだけに--lockedを--frozenへ替えたり、lockを削除したりする対処は更新漏れを隠します。
CIとDockerでの使い分け
CIで現在性だけを検査するならuv lock --check、現在性を検査しながら環境も同期するならuv sync --lockedが適します。Dockerでは例外的に、workspaceメンバーの全pyproject.tomlをまだコピーしていない中間レイヤーで--frozenを使い、全ファイルのコピー後に--lockedで検査する構成がuv公式Dockerガイドに示されています。したがって、--frozen自体が常に誤りなのではなく、整合性検査をどの段階で行うかが重要です。
よくある質問
パッケージの新版が公開されると、lockは古い扱いになりますか?
uvは単純なファイル文字列差分ではなく、lockがプロジェクトメタデータに対して現在も有効かを確認します。依存の追加や、既存のlocked版を許容しなくなる制約変更では更新が必要です。一方、locked版を引き続き許容する制約変更や、新しい版が公開されたことだけで必ず古いlockになるわけではありません。
--lockedが成功すれば、依存不足やアプリの不具合も防げますか?
--lockedやuv lock --checkの成功は、アプリケーションの正常動作まで保証しません。依存グループやextrasの選択、別プロジェクトの実行、別Python環境を見ていることによる未導入は、lock更新漏れとは分けて確認します。
依存は入るのに自作コマンドだけ見つからない場合
lock更新漏れとは別に、プロジェクト本体のインストール設定を確認します。uvのproject.scriptsとパッケージ設定を確認する手順を参照してください。


コメント