bug: "Module not loaded" reported for modules that loaded correctly
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 4/5
- Thời gian dự kiến
- 3-5 ngày
- Mức phù hợp với người mới
- 45/100
Hướng nghiên cứu
The issue is in warnings.go's unresolvedModules() function, comparing terraform.Block.ID(). The root cause involves block expansion and cloning in parser/load_module.go and pkg/iac/terraform/block.go. Start by examining the linked PR for the fix approach, then look at the testdata/lateexpansion fixture to reproduce. Understanding the module loading flow and the ID() vs ModuleKey() distinction is key. Done means the warning no longer appears for correctly loaded modules.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Summary
unresolvedModules() in warnings.go emits
Module not loaded. Did you run `terraform init`?
Module 'module "claude_code[0]"' in file ".terraform/modules/workspace/main.tf:26,1-21" cannot be resolved. This module will be ignored.
for modules that resolved, contributed all of their blocks, and rendered all of
their parameters. Reported by a customer on Coder v2.34.9 with a registry
sourced module; reproduced from source on preview@main.
Root cause
The check compares terraform.Block.ID() between the enumerated module block
and the ModuleBlock() pointer the module's own blocks captured. In the pinned
trivy fork ID() is a per-instance UUID (pkg/iac/terraform/block.go:92) that
Clone() regenerates, and a module block is cloned whenever count or
for_each is expanded.
Expansion can happen after the module's blocks captured their pointer:
EvaluateAllexpands blocks while thecount/for_eachvalue is still
unknown, so the original block stays ine.blocks.loadModulesexpands a copy of the module block list
(parser/load_module.go:38) and does not write it back. The submodule's
blocks capture that clone.- The post-submodule
evaluateSteps()expandse.blocksagain, now that the
value is known, putting a different clone into the evaluated set.
The two instances can never compare equal, so the warning is unconditional. Any
module gated on a value that resolves late is affected; the gate does not have
to be visible at the module's own call site.
Reproduction
module "gate" { source = "./modules/gate" } # outputs enabled = true
module "ai" {
source = "./modules/ai"
count = module.gate.enabled ? 1 : 0 # resolves late
}
preview -d . --log-level error reports module "ai[0]" as unresolved, and no
Failed to load module line is logged at any level, because the module did
load. Full fixture in the linked PR (testdata/lateexpansion).
Evidence that the graph is intact
Instrumenting preview.Preview after EvaluateAll on a template with nine
declared module blocks:
- all nine keys in
.terraform/modules/modules.jsonare loaded; - every resource address in
terraform planis present in the evaluated graph,
including those inside the flagged modules; - three of the nine module blocks have content but are not marked used by
ID(), whileModuleKey()marks all of them used; - the flagged modules' parameters render, including one three modules deep.
Impact
DiagnosticModuleNotLoaded is warning level, so the render succeeds with a
reduced parameter set. On Coder releases without coder/coder#29108 that can cost
stored parameter values (coder/coder#29099). On current main the guard is
present, and there the false positive instead pins affected templates into
"incomplete render" permanently, which suppresses cleanup of values for
parameters the template genuinely removed. Either way the diagnostic is
load bearing and currently unreliable.
Fix
Key the comparison on the declaration rather than the block instance. See the
linked PR.
Known remaining case
A module whose blocks are all removed during expansion (for example a single
resource with for_each = {}) contributes nothing to the graph and is still
reported as not loaded. That is the "completely empty module" limitation the
existing code comment acknowledges. Fixing it properly means returning the
evaluator's real load failures
(parser/load_module.go:47 logs them at Error level and nothing returns them)
instead of inferring resolution. Worth a separate issue.
Filed by Coder Agents on behalf of @angrycub.
- Ngôn ngữ chính
- Go
- Star
- 9
- Fork
- 5
- Merge trung bình
- 5 ngày 17 giờ
- Pull request đã merge (30 ngày)
- 5
Hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của coder/preview
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 76/100
-
bug
-
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 35/100
-
upstream
Tất cả issue của coder/preview
Issue tương tự
-
bug github_actions
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100
registrystack/registry-stack#1393 ·
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100
JakeChampion/lang#10213 ·
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 70/100
oasisprotocol/oasis-sdk#2523 ·
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 70/100