Skip to content

Conversation

@denis256
Copy link
Member

@denis256 denis256 commented Oct 29, 2025

Description

Before this fix:

image

After this fix:

image

Fixes #4983.

TODOs

Read the Gruntwork contribution guidelines.

  • I authored this code entirely myself
  • I am submitting code based on open source software (e.g. MIT, MPL-2.0, Apache)]
  • I am adding or upgrading a dependency or adapted code and confirm it has a compatible open source license
  • Update the docs.
  • Run the relevant tests successfully, including pre-commit checks.
  • Include release notes. If this PR is backward incompatible, include a migration guide.

Release Notes (draft)

Added / Removed / Updated [X].

Migration Guide

Summary by CodeRabbit

  • Bug Fixes

    • Deprecated configuration syntax now yields clear, early error messages instead of cryptic parse failures.
    • Improved dependency discovery reporting and logging of underlying parse errors.
    • Suppressed parsing errors for include-only/no-settings configs are now skipped when suppression is enabled.
    • Include blocks without labels now surface a deprecation-style error message.
  • Tests

    • Added regression tests and fixtures covering deprecated syntax with exposed includes.
    • Added tests for run --all with generate blocks and exposed includes.

@vercel
Copy link

vercel bot commented Oct 29, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
terragrunt-docs Ready Ready Preview Comment Nov 4, 2025 8:18pm

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 29, 2025

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

📝 Walkthrough

Walkthrough

Adds an early deprecated-configuration detection to partial parsing, refines discovery error-handling to optionally skip include-only/no-settings configs when suppression is enabled, and introduces fixtures and tests validating deprecated dependency-input detection and run-all with generate/expose scenarios.

Changes

Cohort / File(s) Change Summary
Core Parsing Logic
config/config_partial.go
Adds an early DetectDeprecatedConfigurations check at the start of PartialParseConfig (applied to both partial-parse entry paths) to return a clear error for deprecated syntax before any decoding/includes. No public signatures changed.
Discovery & Error Handling
internal/discovery/discovery.go
Adds stderrs alias import, introduces non-fatal path in Parse to skip include-only/no-settings configs when suppressParseErrors is true (uses containsNoSettingsError helper), adds nil check in DiscoverDependencies, and changes debug logging to iterate/unwrap errors instead of %w formatting.
Deprecated Syntax Test Fixtures
New files
test/fixtures/parsing/exposed-include-with-deprecated-inputs/child/terragrunt.hcl, test/fixtures/parsing/exposed-include-with-deprecated-inputs/compcommon.hcl, test/fixtures/parsing/exposed-include-with-deprecated-inputs/dep/terragrunt.hcl, test/fixtures/parsing/exposed-include-with-deprecated-inputs/root.hcl
Adds fixtures that expose an include using deprecated dependency.*.inputs.* syntax to exercise detection when expose = true.
Run-All + Generate Fixtures
New files
test/fixtures/regressions/parsing-run-all-with-generate/root.hcl, test/fixtures/regressions/parsing-run-all-with-generate/services-info/main.tf, test/fixtures/regressions/parsing-run-all-with-generate/services-info/terragrunt.hcl, test/fixtures/regressions/parsing-run-all-with-generate/services/test1/main.tf, test/fixtures/regressions/parsing-run-all-with-generate/services/test1/terragrunt.hcl
Adds multi-module fixtures with generate blocks, exposed includes, and mock dependency outputs to validate run-all behavior with generate/expose interactions.
Parse Test Registry
test/integration_parse_test.go
Marks fixtures/parsing/exposed-include-with-deprecated-inputs/compcommon.hcl as a knownBadFile so parsing of that fixture is expected to fail and be skipped by the heavy parser.
Regression Tests
test/integration_regressions_test.go
Adds testFixtureParsingDeprecated constant and three tests: TestExposedIncludeWithDeprecatedInputsSyntax, TestRunAllWithGenerateAndExpose, and TestRunAllWithGenerateAndExpose_WithProviderCacheAndExcludeExternal.
Strict-mode Error Message Update
test/integration_strict_test.go
Updates expected error message for bare include blocks to the new deprecation message: "Using an include block without a label is deprecated. Please use the include block with a label instead."

Sequence Diagram(s)

sequenceDiagram
    participant Caller
    participant PartialParseConfig
    participant DetectDeprecatedConfigurations
    participant ParsingLogic

    Caller->>PartialParseConfig: Call PartialParseConfig()
    PartialParseConfig->>DetectDeprecatedConfigurations: Run early detection

    alt Deprecated syntax detected
        DetectDeprecatedConfigurations-->>PartialParseConfig: Return deprecated-config error
        PartialParseConfig-->>Caller: Return error (stop)
    else No deprecated syntax
        DetectDeprecatedConfigurations-->>PartialParseConfig: OK
        PartialParseConfig->>ParsingLogic: Proceed with decode/includes
        ParsingLogic-->>PartialParseConfig: Parsed partial config
        PartialParseConfig-->>Caller: Return config
    end
Loading
sequenceDiagram
    participant Discover
    participant Parse
    participant PartialParseConfig
    participant containsNoSettingsError

    Discover->>Parse: Call Parse(path, suppressParseErrors)
    Parse->>PartialParseConfig: Call PartialParseConfig(path)

    alt PartialParseConfig returns error
        PartialParseConfig-->>Parse: Return error
        Parse->>containsNoSettingsError: Check error for "no settings" (when suppression enabled)

        alt containsNoSettingsError == true && suppressParseErrors
            containsNoSettingsError-->>Parse: True
            Parse-->>Discover: Log debug, return nil (skip include-only config)
        else
            Parse-->>Discover: Return error (propagate)
        end
    else PartialParseConfig succeeds
        PartialParseConfig-->>Parse: Return config
        Parse-->>Discover: Return parsed config
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Files needing closer attention:
    • config/config_partial.go — ensure deprecated-detection check covers all partial-parse entry paths and doesn't change semantics for valid configs.
    • internal/discovery/discovery.go — verify containsNoSettingsError correctly unwraps and classifies errors and that suppressed-path logging is appropriate.
    • New tests/fixtures — confirm expected failures and that fixtures accurately exercise the scenarios.

Possibly related PRs

Suggested reviewers

  • wakeful
  • yhakbar

Pre-merge checks and finishing touches

✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed Title clearly summarizes the main focus: fixing discovery parsing error handling issues.
Description check ✅ Passed Description includes issue reference, detailed change summary, before/after evidence, and completed checklist items.
Linked Issues check ✅ Passed Changes directly address #4983: early deprecated config detection, include-only config skipping, cleaner error logging without %w artifacts, and test fixtures validating the fixes.
Out of Scope Changes check ✅ Passed All changes are in-scope: parsing/discovery fixes, test fixtures for regression validation, and Runner pool log formatting correction directly support issue resolution.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@denis256 denis256 marked this pull request as ready for review October 30, 2025 11:14
@denis256 denis256 requested a review from yhakbar as a code owner October 30, 2025 11:14
yhakbar
yhakbar previously approved these changes Oct 30, 2025
if suppressParseErrors && containsNoSettingsError(err) {
l.Debugf("Skipping include-only config during discovery: %s", parseOpts.TerragruntConfigPath)

// Store an empty partial config to avoid nil dereferences in subsequent dependency discovery
Copy link
Collaborator

Choose a reason for hiding this comment

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

This is odd to me. Why don't we just nil check later?

yhakbar
yhakbar previously approved these changes Oct 30, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3833956 and b99b08a.

📒 Files selected for processing (1)
  • test/integration_regressions_test.go (2 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.go

⚙️ CodeRabbit configuration file

Review the Go code for quality and correctness. Make sure that the Go code follows best practices, is performant, and is easy to understand and maintain.

Files:

  • test/integration_regressions_test.go
🧠 Learnings (2)
📓 Common learnings
Learnt from: jorhett
Repo: gruntwork-io/terragrunt PR: 1234
File: errors/multierror.go:35-39
Timestamp: 2025-09-10T04:41:35.652Z
Learning: In Terragrunt's MultiError.Error() method, checking for the exact string "exit status 2" and returning it directly is not a brittle hack but a semantic fix. Terraform's --detailed-exitcode flag uses exit code 2 to mean "plan succeeded with changes" (not an error), so when multiple modules return this status, it should not be wrapped in "Hit multiple errors:" formatting as that misrepresents successful operations as errors.
📚 Learning: 2025-11-03T04:40:00.989Z
Learnt from: ThisGuyCodes
Repo: gruntwork-io/terragrunt PR: 5041
File: test/fixtures/hclvalidate/valid/duplicate-attributes-in-required-providers/main.tf:2-7
Timestamp: 2025-11-03T04:40:00.989Z
Learning: In the terragrunt repository, test fixtures under test/fixtures/hclvalidate/valid/ are intentionally testing that INPUT validation succeeds even when Terraform code contains syntax errors or other issues unrelated to input validation (e.g., duplicate attributes, circular references, invalid locals). The "valid" designation means "valid for input validation purposes" not "syntactically valid Terraform/OpenTofu code".

Applied to files:

  • test/integration_regressions_test.go
🧬 Code graph analysis (1)
test/integration_regressions_test.go (2)
test/helpers/package.go (3)
  • CleanupTerraformFolder (879-886)
  • CopyEnvironment (89-102)
  • RunTerragruntCommandWithOutput (1004-1008)
util/file.go (1)
  • JoinPath (626-628)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: license_check / License Check
  • GitHub Check: lint / lint
  • GitHub Check: Pull Request has non-contributor approval
  • GitHub Check: Pull Request has non-contributor approval
  • GitHub Check: build-and-test

Comment on lines +312 to +316
// Set TG_PROVIDER_CACHE=1 and use --queue-exclude-external as in the repro steps
stdout, stderr, err := helpers.RunTerragruntCommandWithOutput(
t,
"terragrunt run --all --queue-exclude-external plan --non-interactive --working-dir "+rootPath,
)
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Set TG_PROVIDER_CACHE so this regression test actually covers the reported scenario.

The comment says we mirror the repro flags, but the code never sets TG_PROVIDER_CACHE=1. Without that env var, this test won’t catch regressions that only surface when the provider cache is enabled—the exact case called out in issue #4983. Please set the env var before invoking Terragrunt so the test exercises the intended code path.

 func TestRunAllWithGenerateAndExpose_WithProviderCacheAndExcludeExternal(t *testing.T) {
 	t.Parallel()
 
+	t.Setenv("TG_PROVIDER_CACHE", "1")
+
 	testFixture := "fixtures/regressions/parsing-run-all-with-generate"

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In test/integration_regressions_test.go around lines 312 to 316, the test
invokes Terragrunt with the repro flags but never sets TG_PROVIDER_CACHE=1 so it
won't exercise the provider-cache code path; set TG_PROVIDER_CACHE=1 before
running the command (either by passing an env map into
helpers.RunTerragruntCommandWithOutput if supported, or by calling
os.Setenv("TG_PROVIDER_CACHE","1") and deferring restore to the previous value)
so the test runs with the provider cache enabled while keeping the existing
command args unchanged.

@denis256 denis256 marked this pull request as draft November 4, 2025 20:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Unrecoverable parse error for ./terragrunt.hcl: Could not find Terragrunt configuration settings in ./terragrunt.hcl

3 participants