できない.dev

Go で `cannot find module providing package` エラーが解消できない

`go build` / `go run` で `cannot find module providing package` が出る場合、go.mod 未登録、GOPROXY / GOPRIVATE の設定漏れ、ローカル参照の replace 未指定、import パスのタイポが主原因。
まず `go mod tidy` を流し、それでも消えなければ環境変数とパスを順に疑う。

#go#modules#go-mod#import

公開: 更新:

要約

Go のモジュール解決は go.mod の require と GOPROXY 経由のダウンロードで成り立つ。cannot find module providing package が出た場合、(1) go.mod に require が無い、(2) GOPROXY 経路で取得できない (private / 認証)、(3) ローカル参照が未設定、(4) import パスのタイポ、のいずれか。
まず go mod tidy を流し、それでも消えなければ環境変数とパスを順に疑う。

よくある原因

  1. go.mod 未登録: 新しい依存を import したが go mod tidy を流していない
  2. GOPROXY 経路の失敗: private repo / 社内 GitLab を public proxy 経由で取りに行き 410 / 404 になる
  3. ローカルモジュール参照: 同一ワークスペース内の別モジュールを使いたいのに replace 指定が無い
  4. import パスのタイポ: 大文字小文字違い、v2 のサブパス漏れ

解決策

1. go mod tidy を流す

go mod tidy

go mod tidy は import 文を解析して不足する require を追加・未使用を削除する。
CI で go mod tidy -check 相当を回せばドリフト検知もできる。

2. private リポジトリは GOPRIVATE を設定

GOPROXY のデフォルト proxy.golang.org は private を取得できないので、GOPRIVATE と git の insteadOf を組み合わせる。

go env -w GOPRIVATE="github.com/yourorg/*,gitlab.example.com/*"
git config --global url."git@github.com:".insteadOf "https://github.com/"

checksum DB 経由のフェッチも避けたければ GONOSUMCHECK / GOSUMDB=off を合わせて指定する。

3. ローカルモジュールは replace で上書き

開発中の別モジュールを参照するには replace を使う。

go mod edit -replace=example.com/foo=../foo
go mod tidy

go.mod に replace example.com/foo => ../foo が追記される。

4. import パスを正確に書く

v2 以降のメジャーバージョンは import パスにバージョンが入る (github.com/foo/bar/v2)。
リポジトリ URL とは違うので、go.mod の require 行とコードの import 文を必ず突き合わせる。

この記事は役立ちましたか?