gitlabhq/gitlabhq · error · ArgumentError
Invalid relation: #{entry.inspect}
Error message
Invalid relation: #{entry.inspect} What it means
Ci::Preloaders::CommitStatusPreloader's relation filter raises ArgumentError, "Invalid relation: #{entry.inspect}" when an element of the relations argument is neither an object responding to to_sym (Symbol/String) nor a Hash. Each entry must resolve to a reflection name on the klass (commit statuses) or a Hash whose keys are reflection names; anything else — Integer, Array, nil — is rejected as invalid.
Source
Thrown at app/models/ci/preloaders/commit_status_preloader.rb:41
def objects(klass)
@statuses.select { |job| job.is_a?(klass) }
end
def associations(klass, relations)
klass_reflections = klass.reflections.keys.map(&:to_sym).to_set
result = []
relations.each do |entry|
if entry.respond_to?(:to_sym)
result << entry.to_sym if klass_reflections.include?(entry.to_sym)
elsif entry.is_a?(Hash)
entry = entry.select do |key, _value|
klass_reflections.include?(key.to_sym)
end
result << entry if entry.present?
else
raise ArgumentError, "Invalid relation: #{entry.inspect}"
end
end
result
end
end
end
end
View on GitHub (pinned to 55ee20384a)
Solutions
- Pass a flat array of Symbols/Strings and/or Hashes only, e.g. [:project, :runner, { tags: :pipeline }]
- Flatten and compact the list before calling: relations.flatten.compact
- Filter names against the model's reflections before invoking if the list is user-derived
Example fix
# before
relations = [:project, [:runner, nil]] # inner Array + nil entries -> raises
CommitStatusPreloader.new(statuses).preload(relation_names: relations)
# after
relations = [:project, :runner, { tags: {} }].flatten.compact
CommitStatusPreloader.new(statuses).preload(relation_names: relations) Defensive patterns
Strategy: type-guard
Validate before calling
relations = relations.flatten.compact
raise ArgumentError, relations.inspect unless relations.all? { |r| r.respond_to?(:to_sym) || r.is_a?(Hash) }
# names must also exist as reflections on the preloaded klass
valid = Ci::Build.reflect_on_all_associations.map { |_, rel| rel.name.to_s }
relations.select! { |r| valid.include?(r.to_s) } unless relations.all?(Hash) Type guard
def valid_preload_entries?(entries)
entries.flatten.compact.all? { |e| e.respond_to?(:to_sym) || e.is_a?(Hash) }
end Try / catch
begin
Ci::Preloaders::CommitStatusPreloader.new(statuses).preload(relation_names: relations)
rescue ArgumentError => e
raise unless e.message.start_with?('Invalid relation:')
# log the inspected entry and fall back to a hardcoded safe relation list
end Prevention
- Keep preload relation lists as flat symbol/hash literals, not dynamically nested arrays
- Never feed user-supplied includes parameters straight into preloaders
- Compact and flatten merged relation lists before use
When it happens
Trigger: Calling the preloader with nested arrays like [:stage, [:tags]] where the inner array element is itself an Array; passing nil inside the list (e.g. from params[relation]&.to_a); passing an AR object or integer id instead of a relation name.
Common situations: Building preload lists dynamically from user-supplied `includes` parameters; merging hardcoded and computed relation lists where one side yields arrays or nils; refactoring symbol lists into nested structures.
Related errors
- pipeline not fully loaded
- Contact #{contact_id} is invalid.
- UnpersistedJobError
- only a single id is supported
- TooManyTagsError
AI-assisted analysis of gitlabhq/gitlabhq@55ee20384a (2026-08-21).
Data as JSON: /api/errors/e504bf709cb6f7f9.
Report an issue: GitHub.