github-linguist/linguist · error · ArgumentError
Duplicate language name: #{language.fs_name}
Error message
Duplicate language name: #{language.fs_name} What it means
Language.create also indexes each language's optional filesystem name (fs_name) into the same @name_index used for names, and rejects a duplicate. Note a latent bug in the raise itself: the line is `raise ArgumentError "Duplicate language name: ..."` — missing the comma between the exception class and the message. Ruby parses this as a call to an undefined method `ArgumentError(msg)`, so when this branch fires you actually get a NameError ('undefined method `ArgumentError`'), not the intended ArgumentError. The intended meaning is that two languages claim the same on-disk name.
Source
Thrown at lib/linguist/language.rb:61
#
# Returns a Language object
def self.create(attributes = {})
language = new(attributes)
@languages << language
# All Language names should be unique. Raise if there is a duplicate.
if @name_index.key?(language.name)
raise ArgumentError, "Duplicate language name: #{language.name}"
end
# Language name index
@index[language.name.downcase] = @name_index[language.name.downcase] = language
# Index filesystem name if defined
if language.fs_name
if @name_index.key?(language.fs_name)
raise ArgumentError "Duplicate language name: #{language.fs_name}"
end
@index[language.fs_name.downcase] = @name_index[language.fs_name.downcase] = language
end
language.aliases.each do |name|
# All Language aliases should be unique. Raise if there is a duplicate.
if @alias_index.key?(name)
raise ArgumentError, "Duplicate alias: #{name}"
end
@index[name.downcase] = @alias_index[name.downcase] = language
end
language.extensions.each do |extension|
if extension !~ /^\./
raise ArgumentError, "Extension is missing a '.': #{extension.inspect}"
end
View on GitHub (pinned to b45dbe9b28)
Solutions
- Grep languages.yml for the colliding fs_name value and remove or rename it on your new entry (fs_name is optional).
- If the collision is with another language's name (not fs_name), pick a different fs_name; names and fs_names share one index.
- If you are fixing the library itself, correct the raise to `raise ArgumentError, "Duplicate language name: #{language.fs_name}"` so the intended error is what users see.
- If you hit a NameError mentioning `ArgumentError`, you have landed on this exact branch — resolve the fs_name duplication as above.
Example fix
# before (lib/linguist/languages.yml) C: type: programming MyC: fs_name: C type: programming # after C: type: programming MyC: type: programming
Defensive patterns
Strategy: validation
Validate before calling
fs_name = "C"
taken = Linguist::Language.all.any? do |l|
l.fs_name&.downcase == fs_name.downcase || l.name.downcase == fs_name.downcase
end
raise ArgumentError, "fs_name already registered: #{fs_name}" if taken Try / catch
# NB: the raise at language.rb:61 is missing a comma, so this branch actually
# throws NameError (undefined method `ArgumentError`), not ArgumentError.
begin
Linguist::Language.create(attributes)
rescue ArgumentError, NameError => e
raise unless e.message.include?("ArgumentError") || e.message =~ /Duplicate language name/
end Prevention
- fs_name is optional — omit it unless the language needs a distinct on-disk name.
- Remember names and fs_names share one index; check both when adding entries.
- Watch for NameError mentioning `ArgumentError` — that is this duplicate-fs_name branch firing.
When it happens
Trigger: 1) Two entries in languages.yml declaring the same fs_name (e.g. both `fs_name: C`). 2) A language whose fs_name collides with another language's downcased name (both live in @name_index; the check compares fs_name against downcased stored keys). 3) Calling Linguist::Language.create with a fs_name already registered. When it fires, the visible failure is NameError from the malformed raise at language.rb:61.
Common situations: Adding a new language that reuses a filesystem name like 'C' or 'Shell' already claimed by an adjacent language; copy-pasting a languages.yml entry and editing the name but forgetting to change fs_name; maintaining a fork with custom languages that collide with names added upstream.
Related errors
- Duplicate language name: #{language.name}
- Duplicate alias: #{name}
- Extension is missing a '.': #{extension.inspect}
- invalid type: #{@type}
- read_index is deprecated
AI-assisted analysis of github-linguist/linguist@b45dbe9b28 (2026-08-21).
Data as JSON: /api/errors/6dea07a3466bcbfd.
Report an issue: GitHub.