Only one level of includes is allowed
Fixes Terragrunt's 'Only one level of includes is allowed' by flattening chained includes. Use when a unit includes a file that itself includes another file. Not for genuinely circular A-includes-B-includes-A loops (same fix applies).
TL;DR: Terragrunt allows exactly ONE level of include. If your unit includes a file that itself has an include block (the classic _envcommon file that includes the root), the run fails. Include every file directly in the unit instead of chaining.
a/b/terragrunt.hcl includes a/mid.hcl, which itself includes root.hcl.
Only one level of includes is allowed.Steps
- Map the chain: which file does the unit include, and does THAT file have its own
includeblock?
Expected: you find the second hop (often an _envcommon file including the root).
- Flatten it: give the unit both includes directly with distinct labels:
include "root" {
path = find_in_parent_folders("root.hcl")
}
include "envcommon" {
path = "${dirname(find_in_parent_folders("root.hcl"))}/_envcommon/service.hcl"
merge_strategy = "deep"
} Expected: no included file contains an include block.
- Re-run.
Expected: the error is gone.
When this applies
- The error names a chain of two or more includes.
_envcommon-style shared files that include the root, included by units.- Deep trees where each level includes the one above.
When it doesn't apply
- A single include that fails to resolve: that's
Include configuration not found, different fix. - Merge surprises with multiple sibling includes: that's
merge_strategy(shallow vs deep), not chaining.
Tool versions
All Terragrunt 1.x (verified on 1.1.3; upstream issue #1566 tracks lifting the limit).
Why it happens
Includes are resolved in a single pass with no recursion support. Chained includes would need multi-pass resolution, which Terragrunt doesn't do, so it rejects chains outright rather than resolving them partially.
Edge cases
- Include blocks merge by label and are additive, so flattening doesn't lose config; it just moves the declarations.
- Anchor paths to a marker file (
find_in_parent_folders("root.hcl")) rather than counting../segments, which break when a unit moves.
Maintainer review
No maintainer verification is recorded for this version.
This records the version a maintainer checked. It does not assert that the version is the latest upstream release.