Skip to content

Fix "Multiple sources!" error for case-variant Terraform/OpenTofu provider declarations#14434

Merged
thavaahariharangit merged 9 commits into
mainfrom
copilot/fix-multiple-provider-sources
Mar 18, 2026
Merged

Fix "Multiple sources!" error for case-variant Terraform/OpenTofu provider declarations#14434
thavaahariharangit merged 9 commits into
mainfrom
copilot/fix-multiple-provider-sources

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 13, 2026

Fixes #14430

Terraform/OpenTofu provider source addresses are case-insensitive, but Dependabot was doing a case-sensitive comparison when deduplicating sources across files. When the same provider appeared as e.g. "Azure/azapi" in one file and "azure/azapi" in another, DependencySet would merge them by name (case-insensitive) but retain both source hashes — causing source_details to raise RuntimeError: "Multiple sources!" and kill the job.

Changes

  • terraform/lib/dependabot/terraform/file_parser.rb — Normalize namespace and name to lowercase in provider_source_from, so module_identifier is always lowercase regardless of how the source is written in .tf files.
  • opentofu/lib/dependabot/opentofu/file_parser.rb — Same fix.
  • Test fixtures (provider_with_mixed_case) — Added a second .tf file per ecosystem with the lowercase variant of the provider, alongside the existing mixed-case providers.tf, to exercise cross-file deduplication.
  • Specs — Added tests verifying that mixed-case provider declarations across files are normalized to lowercase and do not raise.
# Before: two distinct source hashes, raises "Multiple sources!"
{ type: "provider", registry_hostname: "registry.terraform.io", module_identifier: "Azure/azapi" }
{ type: "provider", registry_hostname: "registry.terraform.io", module_identifier: "azure/azapi" }

# After: both normalize to the same hash
{ type: "provider", registry_hostname: "registry.terraform.io", module_identifier: "azure/azapi" }

Anything you want to highlight for special attention from reviewers?

The normalization happens in provider_source_from, which means both dependency_name and module_identifier are lowercased. This is intentional — the Terraform and OpenTofu registries are case-insensitive for provider addresses, so the canonical form is lowercase. DependencySet already does case-insensitive name matching, so this doesn't affect merging behaviour.

registry_source_details_from (for modules, not providers) is not changed — the issue specifically concerns providers.

How will you know you've accomplished your goal?

The provider_with_mixed_case fixture now spans two files with differently-cased declarations of the same provider. The new specs assert a single merged dependency with a lowercase module_identifier and no raised error.

Checklist

  • I have run the complete test suite to ensure all tests and linters pass.
  • I have thoroughly tested my code changes to ensure they work as expected, including adding additional tests for new functionality.
  • I have written clear and descriptive commit messages.
  • I have provided a detailed description of the changes in the pull request, including the problem it addresses, how it fixes the problem, and any relevant details about the implementation.
  • I have ensured that the code is well-documented and easy to understand.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • api.launchpad.net
    • Triggering command: /usr/bin/add-apt-repository add-apt-repository -y ppa:git-core/ppa grep rity.crt -q la/vTrus_ECC_Root_CA.crt e -1_all.deb 64.deb b grep rtif�� C_NUMBER) -x e libcryptsetup12_readlink p.ci /usr/bin/rm sed (dns block)
  • checkpoint-api.hashicorp.com
    • Triggering command: /usr/local/bin/terraform terraform --version (dns block)
  • ports.ubuntu.com
    • Triggering command: /usr/lib/apt/methods/http /usr/lib/apt/methods/http (dns block)

If you need me to access, download, or install something from one of these locations, you can either:


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

…arsers

When the same provider is declared with different casing (e.g. "Azure/azapi"
vs "azure/azapi") across multiple files, Dependabot was raising a
"Multiple sources!" RuntimeError because the source hashes differed.

Terraform and OpenTofu treat provider source addresses as case-insensitive,
so normalize namespace and name to lowercase in `provider_source_from`
to ensure consistent module_identifier values regardless of casing.

Co-authored-by: GitHub Copilot <copilot@github.com>

Co-authored-by: thavaahariharangit <164553783+thavaahariharangit@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix multiple provider sources issue in Terraform Fix "Multiple sources!" error for case-variant Terraform/OpenTofu provider declarations Mar 13, 2026
@github-actions github-actions Bot added L: terraform Terraform packages L: opentofu labels Mar 16, 2026
…oviders

- Add case-insensitive flag (i) to provider_declaration_regex and
  registry_declaration_regex in both Terraform and OpenTofu file updaters,
  so manifest files with mixed-case source addresses (e.g. Mongey/confluentcloud)
  are matched correctly when dependency names are normalized to lowercase.
- Remove leftover main.tf fixture files from provider_with_mixed_case that
  conflicted with the file_updater test (duplicate required_providers blocks).
- Add manifest version constraint assertions to file_updater tests to verify
  .tf files are updated, not just lockfiles.
@thavaahariharangit thavaahariharangit marked this pull request as ready for review March 16, 2026 14:44
@thavaahariharangit thavaahariharangit requested a review from a team as a code owner March 16, 2026 14:44
Copilot AI review requested due to automatic review settings March 16, 2026 14:44
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes a Terraform/OpenTofu parsing edge case where provider source addresses that differ only by letter case (across multiple .tf files) could cause Dependabot to treat them as distinct sources and raise RuntimeError: "Multiple sources!".

Changes:

  • Normalize Terraform/OpenTofu provider source address components (hostname, namespace, name) to lowercase in provider_source_from.
  • Make provider/module declaration matching in the Terraform/OpenTofu file updaters case-insensitive (regex /i) so updates still apply when manifests use mixed-case addresses.
  • Add fixtures and specs for cross-file mixed-case provider declarations to ensure parsing deduplicates correctly and does not raise.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated no comments.

Show a summary per file
File Description
terraform/lib/dependabot/terraform/file_parser.rb Lowercases provider source address components to canonicalize provider identity across files.
opentofu/lib/dependabot/opentofu/file_parser.rb Same normalization for OpenTofu provider sources.
terraform/lib/dependabot/terraform/file_updater.rb Makes declaration regexes case-insensitive so updates still match mixed-case manifest content.
opentofu/lib/dependabot/opentofu/file_updater.rb Same regex flag change for OpenTofu updates.
terraform/spec/fixtures/projects/provider_with_mixed_case_sources/main.tf Adds lowercase provider source variant in a second file to test cross-file dedupe.
terraform/spec/fixtures/projects/provider_with_mixed_case_sources/providers.tf Adds mixed-case provider source variant to pair with main.tf.
opentofu/spec/fixtures/projects/provider_with_mixed_case_sources/main.tf Same fixture setup for OpenTofu.
opentofu/spec/fixtures/projects/provider_with_mixed_case_sources/providers.tf Same fixture setup for OpenTofu.
terraform/spec/dependabot/terraform/file_parser_spec.rb New spec verifying lowercase normalization and no “Multiple sources!” raise.
opentofu/spec/dependabot/opentofu/file_parser_spec.rb Same spec coverage for OpenTofu.
terraform/spec/dependabot/terraform/file_updater_spec.rb Updates expectations to the new canonical lowercase provider identifier and adds manifest-constraint assertion.
opentofu/spec/dependabot/opentofu/file_updater_spec.rb Same updates for OpenTofu updater expectations.

@Yantrio
Copy link
Copy Markdown
Contributor

Yantrio commented Mar 16, 2026

This same issue also affects registry modules:

registry_source_details_from in both parsers don't normalize module_identifier to lowercase, and registry_declaration_regex in both updaters is missing the i flag that was added to the provider regexes.

I think the rest looks good to me though. However I'm not a ruby expert.

Registry module source addresses are case-insensitive, like provider source
addresses. Normalize module_identifier and registry_hostname to lowercase in
registry_source_details_from for both Terraform and OpenTofu parsers to avoid
'Multiple sources!' errors when modules are declared with different casing
across files.
Copy link
Copy Markdown
Contributor

Addressed in 0188504 — added .downcase normalization to module_identifier and registry_hostname in registry_source_details_from for both Terraform and OpenTofu parsers.

Note: the registry_declaration_regex in both updaters already had the i flag added as part of the original PR changes (}mxi), so that was already covered.

@Yantrio
Copy link
Copy Markdown
Contributor

Yantrio commented Mar 17, 2026

Addressed in 0188504 — added .downcase normalization to module_identifier and registry_hostname in registry_source_details_from for both Terraform and OpenTofu parsers.

This LGTM, but im not an expert on this codebase. Maybe @diofeher could help? And I am not certain on anything on the terraform side, i can only answer about opentofu here.

@kbukum1
Copy link
Copy Markdown
Contributor

kbukum1 commented Mar 18, 2026

@thavaahariharangit , if we do have dependabot-core issue, we should add something like the following to the PR description.

Fixes https://github.com/dependabot/dependabot-core/issues/14430

or

Closes https://github.com/dependabot/dependabot-core/issues/14430

Copy link
Copy Markdown
Contributor

@kbukum1 kbukum1 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@thavaahariharangit thavaahariharangit merged commit 552ed62 into main Mar 18, 2026
110 of 115 checks passed
@thavaahariharangit thavaahariharangit deleted the copilot/fix-multiple-provider-sources branch March 18, 2026 22:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

L: opentofu L: terraform Terraform packages

Projects

None yet

5 participants