LoadError: cannot load such file — [file_or_gem_name] とは
Rubyでスクリプトを実行した際に「LoadError: cannot load such file — [file_or_gem_name]」というエラーに遭遇することは少なくありません。これは、require や require_relative メソッドが指定されたファイルやライブラリ(Gem)を見つけられなかった場合に発生するエラーです。多くの場合、パスの指定ミスやGemのインストール漏れが原因です。
実行環境ごとのエラーメッセージ
| 環境 | エラーメッセージ |
|---|---|
| Ruby CLI (開発環境) | Traceback (most recent call last):
from your_script.rb:1:in ` |
| Ruby on Rails サーバー (development/production) | Puma caught this error: cannot load such file -- some_gem (LoadError)
/path/to/rails_app/config/application.rb:1:in `require'
/path/to/rails_app/config/application.rb:1:in ` |
| Docker コンテナ内 | standard_init_linux.go:228: exec user process: |
エラーの発生パターン
このエラーは主に以下のようなケースで発生します。
パターン1: パターン1: Gemのインストール漏れまたはパスの不備
# bad_code.rb
# 存在しないGemをrequireしようとしている
require 'non_existent_gem'
puts "This line will not be reached."
使用しようとしているGemがシステムにインストールされていないか、Bundlerを使用している場合に bundle install が実行されていない可能性があります。また、GEM_PATH 環境変数が正しく設定されていない場合も、RubyがGemを見つけられずにこのエラーが発生します。
# good_code.rb
# 必要なGemをGemfileに追加し、bundle install を実行する
# (Gemfileの例)
# source 'https://rubygems.org'
# gem 'rails', '~> 7.0.0'
# gem 'nokogiri'
#
# コンソールで:
# bundle install
# その後、スクリプトでrequireする
require 'nokogiri'
puts "Nokogiri loaded successfully!"
# または、インストール済みのGemを直接require
# gem install rspec
# require 'rspec'
パターン2: パターン2: ローカルファイルのパス指定ミス
# bad_code.rb
# current_dir/lib/my_module.rb が存在しない、またはパスが間違っている
# ディレクトリ構造:
# . (current_dir)
# ├── bad_code.rb
# └── my_module.rb
require 'lib/my_module' # libディレクトリがないため失敗
puts "This line will not be reached."
require や require_relative で自作のRubyファイルを読み込む際、相対パスや絶対パスの指定が誤っているとファイルが見つかりません。require は $LOAD_PATH を、require_relative は現在のファイルのディレクトリを基準にファイルを検索します。
# good_code.rb
# ディレクトリ構造:
# . (current_dir)
# ├── good_code.rb
# └── lib/
# └── my_module.rb
# lib/my_module.rb の内容:
# module MyModule
# def self.hello
# "Hello from MyModule!"
# end
# end
# 正しい相対パスでrequire_relativeを使用
require_relative 'lib/my_module'
puts MyModule.hello
# または、LOAD_PATHに追加してからrequire
# $LOAD_PATH.unshift(File.expand_path('./lib'))
# require 'my_module'
# puts MyModule.hello
パターン3: パターン3: 環境変数 RUBYLIB または GEM_PATH の問題
# bad_code.rb
# 本来はロードパスが通っているはずのディレクトリが環境変数によって上書きされている
# 環境変数設定例:
# export RUBYLIB=/wrong/path
# export GEM_PATH=/wrong/gem/path
require 'some_utility_gem' # 正しいパスにインストールされているのに見つからない
puts "This line will not be reached."
CI/CD環境やDockerコンテナなどで、RUBYLIB や GEM_PATH といった環境変数が意図せず上書きされたり、不適切な値に設定されたりしていると、Rubyが正しいロードパスやGemのインストール場所を見つけられなくなります。これにより、本来利用できるはずのGemやファイルが見つからなくなることがあります。
# good_code.rb
# 環境変数をunsetするか、正しいパスを設定する
# コンソールで:
# unset RUBYLIB
# unset GEM_PATH
# または
# export RUBYLIB=/path/to/correct/libs
# export GEM_PATH=/path/to/correct/gems
# その後、スクリプトを実行
require 'some_utility_gem'
puts "Gem loaded successfully after correcting environment variables!"
# Rubyコード内で一時的にロードパスを追加することも可能
# $LOAD_PATH.unshift('/path/to/additional/lib')
# require 'my_custom_lib'

特に require と require_relative の使い分けは、プロジェクトが大きくなると混乱しがちですよね。原則として require_relative で自作ファイル、require でGemと覚えると良いですよ。
よくあるバリエーション
cannot load such file — bundler/setup
このエラーは、Bundlerが正しく設定されていないか、bundle install が実行されていない環境でRubyスクリプトを実行しようとした際に発生します。bundler/setup は、Gemfileで定義されたGemのパスをRubyのロードパスに追加するために必要です。
<!-- コンソールで `bundle install` を実行し、その後 `bundle exec ruby your_script.rb` のように実行することで解決します。 -->
```bash
bundle install
bundle exec ruby your_script.rb
```
cannot load such file — active_record
Railsアプリケーションでこのエラーが発生した場合、通常は Gemfile に gem 'rails' が記述されていないか、bundle install が完了していないことを意味します。active_record はRailsフレームワークの主要なコンポーネントであるため、Railsが正しくロードされていないと見つかりません。
<!-- Gemfileに `gem 'rails'` を追加し、`bundle install` を実行します。 -->
```ruby
# Gemfile
gem 'rails', '~> 7.0.0'
```
cannot load such file — ‘my_module’
これは、自身で作成した my_module.rb というファイルがRubyのロードパス ($LOAD_PATH) に含まれていない場合に発生します。require 'my_module' とする代わりに、require_relative を使うか、$LOAD_PATH にモジュールがあるディレクトリを追加する必要があります。
```ruby
# my_script.rb
# ディレクトリ構造: ./lib/my_module.rb
# オプション1: $LOAD_PATH に追加
$LOAD_PATH.unshift(File.expand_path('./lib', __dir__))
require 'my_module'
# オプション2: require_relative を使用
# require_relative 'lib/my_module'
```
フレームワーク別の発生パターン
Ruby on Railsでの発生パターン
Railsアプリケーションでは、Gemfileに記述されたGemが bundle install されていない場合や、require 'rails' が実行される前(例: config/application.rb の読み込み前)にGemを使用しようとすると LoadError が発生します。また、Rails Engine内で独自のモジュールを読み込む際のパス指定ミスもよくある原因です。
# bad_code.rb (Rails)
# Gemfileに "gem 'json'" がない状態で実行
# require 'json'
# puts JSON.parse('{}')
# good_code.rb (Rails)
# Gemfileに "gem 'json'" を追加後、bundle install を実行
# (Gemfile)
# gem 'json'
#
# コンソールで:
# bundle install
# rails s (サーバー起動)
#
# Rails Engine 内のファイル読み込み
# app/engines/my_engine/lib/my_engine/version.rb
# require_relative 'my_engine/some_helper' # 相対パスが重要
puts "JSON module loaded successfully in Rails context."
Sinatraでの発生パターン
軽量なWebフレームワークであるSinatraでも、config.ru でアプリケーションを起動する際に、必要なGemがインストールされていないと LoadError が発生します。また、require_relative を使って複数のファイルに分割されたアプリケーションを読み込む際、基点となるファイルのパスを間違えやすいです。
# bad_code.rb (Sinatra)
# config.ru
# require 'sinatra/base'
# require_relative 'app_controller' # app_controller.rb が存在しない、またはパスが誤っている
# good_code.rb (Sinatra)
# config.ru
# require 'sinatra/base'
# require_relative 'app.rb' # 正しいファイル名を指定
# app.rb の例:
# class MyApp < Sinatra::Base
# get '/' do
# 'Hello from Sinatra!'
# end
# end
# コンソールで:
# rackup config.ru
puts "Sinatra application loaded successfully."
根本原因の特定方法
LoadError のデバッグでは、まずエラーメッセージに表示されているファイル名やGem名を確認し、それが実際に存在するか、正しい場所にインストールされているかを検証します。puts $LOAD_PATH でRubyの検索パスを確認したり、gem list でインストール済みGemの一覧を確認することも有効です。bundle exec を使わずにスクリプトを実行している場合は、bundle exec を試してみましょう。
```ruby
# debug_load_path.rb
puts "--- Current $LOAD_PATH ---"
$LOAD_PATH.each_with_index do |path, i|
puts "#{i}: #{path}"
end
puts "------------------------"
# 存在確認したいファイルやGem名
file_to_check = 'non_existent_gem'
# $LOAD_PATH を手動で検索してみる
found = false
$LOAD_PATH.each do |path|
full_path = File.join(path, "#{file_to_check}.rb")
if File.exist?(full_path)
puts "Found '#{file_to_check}' at #{full_path}"
found = true
break
end
end
unless found
puts "'#{file_to_check}' not found in $LOAD_PATH."
puts "Consider adding the directory containing '#{file_to_check}.rb' to $LOAD_PATH or installing the gem."
end
```
require と require_relative、load の違いと使い分け
Rubyにはファイルを読み込むための複数のメソッドがあります。 require は、Gemや標準ライブラリのように、Rubyのロードパス ($LOAD_PATH) に含まれる場所から一度だけファイルを読み込みます。これは主に外部ライブラリの読み込みに使われます。一方、 require_relative は、現在のファイルを基準とした相対パスでファイルを一度だけ読み込みます。これは、同じプロジェクト内の自作モジュールを読み込む際に便利です。load は、指定されたファイルを $LOAD_PATH に関係なく、毎回読み込みます。これは主に設定ファイルなど、実行時に何度も読み込み直したい場合に使用します。適切なメソッドを選択することが、LoadError を防ぐ上で重要です。
防止策とベストプラクティス
LoadError を防ぐためには、Gemfileを正確に記述し、常に bundle install を実行してから bundle exec でスクリプトを実行する習慣をつけましょう。自作ファイルの場合は、require_relative を適切に使い、ファイルパスの指定ミスをなくすことが重要です。また、CI/CDでテストを実行する際に、正しい環境変数とBundlerコマンドが使われていることを確認します。
```ruby
# Gemfile
source 'https://rubygems.org'
gem 'rails', '~> 7.0.0'
gem 'dotenv'
# my_app.rb (常に bundle exec で実行することを前提)
require 'dotenv/load' # .envファイルをロード
# ロードパスが通っていることを前提とする
# require 'some_module_in_lib_dir'
# もし $LOAD_PATH に追加が必要なら
# $LOAD_PATH.unshift(File.expand_path('../lib', __dir__))
```



Ruby開発の鉄則とも言える bundle exec の徹底は、このエラーだけでなく様々な環境問題を回避するのに役立ちます。ぜひ習慣化してくださいね。


このエラーは一見すると解決が難しそうに見えますが、原因はシンプルであることがほとんどです。落ち着いて一つずつ確認していきましょう!
よくある質問(FAQ)
-
Q本番環境(Docker/Capistrano)でだけ「LoadError」が発生するケースはありますか?
-
A
はい、あります。多くの場合、デプロイ時に
bundle installが正しく実行されていない、または環境変数の設定ミス(GEM_PATHなど)が原因です。Dockerでは、Dockerfile内でGemが正しくインストールされていないか、コンテナ起動時のパス設定が不足している可能性があります。Capistranoでは、デプロイスクリプトがBundlerコマンドを正しく呼び出しているか確認が必要です。
-
QRailsアプリケーションで「LoadError」が発生した場合の具体的なデバッグ方法は?
-
A
まず、エラーメッセージのGem名やファイル名を確認し、
Gemfileに記述があるか、bundle installが完了しているかを確認します。Railsコンソール (rails c) を起動して、問題のGemをrequireしてみてエラーが出るか確認するのも有効です。また、Rails.application.config.eager_load_pathsなど、Railsのロードパス設定を確認することも重要です。
-
Q
Bundler::GemNotFoundとLoadErrorの違いは? -
A
Bundler::GemNotFoundは、BundlerがGemfileに記述されたGemを見つけられない場合に発生します。これは通常、bundle installが未実行か失敗していることを意味します。一方、LoadErrorは、requireメソッドが特定のファイル(Gemを含む)をロードパスから見つけられない場合に発生します。Bundler::GemNotFoundの後にLoadErrorが続くこともあります。
-
QLinterやCIツールで事前に「LoadError」を防ぐ方法はありますか?
-
A
Linter自体が
LoadErrorを直接検出することは難しいですが、RuboCopなどの静的解析ツールでrequireステートメントの記述ルールを強制することは可能です。CIツールでは、bundle checkコマンドを実行してGemfileとGemfile.lockの整合性を確認したり、アプリケーションのユニットテストや統合テストをbundle execで実行することで、必要なGemやファイルがロードできるか事前に検証できます。
-
Qユーザー向けに「LoadError」をハンドリングするにはどうすれば良いですか?
-
A
LoadErrorは通常、アプリケーションの起動時や特定の機能が呼び出された初期段階で発生する致命的なエラーです。ユーザーに直接表示するのではなく、カスタムエラーページ(例: 500 Internal Server Error)を表示するように設定します。エラーログには詳細を記録し、開発者が原因を特定できるようにします。起動前のチェックでGemの存在を確認し、不足していればエラーメッセージと共にアプリケーションを終了させることも可能です。



コメント