OpenTofu This Week: Plan Snapshot Fixes, State Bug Backports and a New Version Output
I looked at the last week of commits in opentofu/opentofu, the open source Terraform fork. Ten commits landed across 64 files, with two state handling bugs fixed and backported to the 1.12 and 1.13 branches, a plan snapshot fix, and a small user visible change: tofu version now prints module versions. Here is what matters if you run OpenTofu in production.
Plan snapshot fix for symbol libraries
The newest commit is the symbol libraries fix in the plan snapshot, merged as PR #4816. The change sits in internal/configs/configload/loader_snapshot.go.
Before the fix, the loader filled in module source files while walking each module. The diff shows this moved to a second pass: addModuleToSnapshot now records the file paths, and LoadConfigWithSnapshot injects the actual source bytes once all sources are loaded. If a file is missing from the sources map, you get a clear Missing source file for snapshot diagnostic instead of a silently incomplete snapshot. Symbol files (.tofu symbol libraries) are now included in that pass, which is what the fix is about. Clearing FilePaths after use also keeps the snapshot JSON output clean.
Not something most users touch directly, but it matters for tooling and any CI that consumes plan snapshots.
Local state bugs, backported to 1.12 and 1.13
Two state handling fixes landed with PR #4811, then got backported to both maintained branches via PR #4812 for 1.13 and PR #4813 for 1.12.
The changes touch internal/states/statemgr/filesystem.go:
- Fix the persist local state bug in the error path on first run. When a run failed on the very first apply, local state was not persisted the way it should be. If you hit odd “state not found” behavior after a failed first run, this is the fix.
- The same PR series covers the local statefile mutate bug on the backport branches.
Worth pulling the next 1.12.x and 1.13.x patch releases for. The 1.13.6 release itself was prepared in PR #4807.
Workdir cleanup and new runtime work
Most of the remaining diff is internal:
- Cleanup of the old workdir implementation (PR #4717) removed the legacy tracking under internal/command/workdir. No behavior change expected.
- RelevantResources now works in the new planning runtime, together with the action reasons fix (PR #4771) and the RelevantAttributes work in PR #4790. These land in internal/engine/planning/plan_managed.go. This is the ongoing rewrite of the plan engine, so expect more commits here.
- Cancellation of interactive input (PR #4755) fixes the uiinput path so a cancelled context does not hang waiting for keyboard input from a tty.
One nice user visible change
PR #4573, implemented in this commit, makes tofu version display installed module versions alongside the OpenTofu version. Simple, and useful when debugging “which module source revision did this run actually use”.
Also merged: diagnostics links now fully qualify the docs/diagnostics.md path (PR #4800), so error codes resolve correctly when printed from subdirectories.
Release pipeline refactor
The release and nightly workflow refactor shipped in three copies: PR #4803 for main, PR #4805 for v1.13 and PR #4806 for v1.12. It reworked .github/workflows/release.yml and nightly.yml, touched .goreleaser.yaml and the release Dockerfiles, and PR #4808 switched backport CI to the preinstalled Go from the worker tool cache. Pure infrastructure, invisible to users, but it should make release runs faster.
What to watch
- Upgrade to the next 1.12.x and 1.13.x patches for the state persist fixes. The first run failure path is exactly where fresh deployments get hurt.
- The new planning runtime work (RelevantResources, RelevantAttributes, action reasons) is active in
internal/engine/planning. Expect behavior parity fixes to keep landing there. - The snapshot file injection pattern in loader_snapshot.go is a good example of the project tightening error reporting rather than swallowing missing files.