github-linguist/linguist · warning · NotImplementedError

read_index is deprecated

Error message

read_index is deprecated

What it means

read_index is a legacy helper on Linguist::Repository that only still works when the underlying source is the Rugged-backed implementation: it raises NotImplementedError ('read_index is deprecated') unless `repository.is_a?(Linguist::Source::RuggedRepository)`. The Repository constructor wraps anything that is not already a Source::Repository in a RuggedRepository for backward compatibility, so the raise specifically means a custom Source::Repository implementation was injected and the old Rugged-specific path (set_attribute_source) cannot run on it. Modern code should use the public analysis API (#language_stats / #cache) instead of this internal helper.

Source

Thrown at lib/linguist/repository.rb:132

    # Public: Return the cached results of the analysis
    #
    # This is a per-file breakdown that can be passed to other instances
    # of Linguist::Repository to perform incremental scans
    #
    # Returns a map of filename => [language, size]
    def cache
      @cache ||= begin
        if @old_commit_oid == @commit_oid
          @old_stats
        else
          compute_stats(@old_commit_oid, @old_stats)
        end
      end
    end

    def read_index
      raise NotImplementedError, "read_index is deprecated" unless repository.is_a? Linguist::Source::RuggedRepository
      repository.set_attribute_source(@commit_oid)
    end

    def current_tree
      raise NotImplementedError, "current_tree is deprecated" unless repository.is_a? Linguist::Source::RuggedRepository
      repository.get_tree(@commit_oid)
    end

    protected
    def compute_stats(old_commit_oid, cache = nil)
      return {} if repository.get_tree_size(@commit_oid, @max_tree_size) >= @max_tree_size

      repository.set_attribute_source(@commit_oid)
      diff = repository.diff(old_commit_oid, @commit_oid)

      # Clear file map and fetch full diff if any .gitattributes files are changed
      if cache && diff.each_delta.any? { |delta| File.basename(delta.new_file[:path]) == ".gitattributes" }
        diff = repository.diff(nil, @commit_oid)

View on GitHub (pinned to b45dbe9b28)

Solutions

  1. Replace the read_index call with the public API: `repo.language_stats` (or `repo.cache`) which works for every source implementation.
  2. If you truly need the git-attributes side effect, call `repo.repository.set_attribute_source(repo.instance_variable_get(:@commit_oid))` only after checking the source type — or better, keep that logic inside your Rugged adapter.
  3. If you control the call site and must keep behavior, gate it: `repo.read_index if repo.repository.is_a?(Linguist::Source::RuggedRepository)`.
  4. Upgrade scripts/tooling that referenced this helper when you bumped the linguist gem version.

Example fix

# before
linguist_repo.read_index
stats = linguist_repo.language_stats

# after
stats = linguist_repo.language_stats
Defensive patterns

Strategy: type-guard

Validate before calling

def rugged_backed?(linguist_repo)
  linguist_repo.repository.is_a?(Linguist::Source::RuggedRepository)
end

linguist_repo.read_index if rugged_backed?(linguist_repo)

Type guard

def supports_legacy_index?(linguist_repo)
  linguist_repo.repository.is_a?(Linguist::Source::RuggedRepository)
end

Try / catch

begin
  linguist_repo.read_index
rescue NotImplementedError => e
  raise unless e.message =~ /read_index is deprecated/
  # source is not Rugged-backed: rely on language_stats instead
end

Prevention

When it happens

Trigger: 1) Constructing Linguist::Repository with your own Linguist::Source::Repository implementation and then calling `repo.read_index`. 2) Old application/test code still calling read_index after upgrading to a linguist version that abstracted sources (5.x). 3) Test doubles standing in for the source, which are not RuggedRepository instances.

Common situations: Upgrading github-linguist in a hosting stack that now passes a non-Rugged source adapter; long-lived internal scripts that poke at repository internals; RSpec specs that build a Repository around a fake source and reuse pre-5.x helper calls.

Related errors


AI-assisted analysis of github-linguist/linguist@b45dbe9b28 (2026-08-21). Data as JSON: /api/errors/2e2be4dd5f388e97. Report an issue: GitHub.