{"record":{"id":"95dedfafe6b456d8","repo":"opentofu/opentofu","slug":"invalid-root-module-source-address-w","errorCode":null,"errorMessage":"invalid root module source address: %w","messagePattern":"invalid root module source address: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/command/temp_new_runtime.go","lineNumber":107,"sourceCode":"\t\tProvisioners:       staticPlugins,\n\t\tWorkspace:          workspace,\n\t}\n\n\t// The new config-loading system wants to work in terms of module source\n\t// addresses rather than raw local filenames, so we'll ask the\n\t// addrs package to parse the path we were given. We need to adjust\n\t// a little though, because this function was designed for parsing\n\t// the \"source\" argument in a module block, not a plain filepath.\n\t// We should add a function in package addrs that's actually intended for\n\t// turning arbitrary filesystem paths in to addrs.LocalSource in the long\n\t// run, but this will do for now.\n\tconfigDir := root.SourceDir\n\tif !filepath.IsAbs(configDir) {\n\t\tconfigDir = \".\" + string(filepath.Separator) + configDir\n\t}\n\trootModuleSource, err := addrs.ParseModuleSource(configDir)\n\tif err != nil {\n\t\tdiags = diags.Append(fmt.Errorf(\"invalid root module source address: %w\", err))\n\t\treturn nil, diags\n\t}\n\n\tconfigCall := &eval.ConfigCall{\n\t\tRootModuleSource:     rootModuleSource,\n\t\tInputValues:          inputValues,\n\t\tAllowImpureFunctions: false,\n\t\tEvalContext:          evalCtx,\n\t}\n\tconfigInst, moreDiags := eval.NewConfigInstance(ctx, configCall)\n\tdiags = diags.Append(moreDiags)\n\tif moreDiags.HasErrors() {\n\t\treturn nil, diags\n\t}\n\treturn configInst, diags\n}\n\n// newRuntimeModules is an implementation of [eval.ExternalModules] that makes","sourceCodeStart":89,"sourceCodeEnd":125,"githubUrl":"https://github.com/opentofu/opentofu/blob/3561785c48c1ce615e7c50261bd351f26053efa2/internal/command/temp_new_runtime.go#L89-L125","documentation":"The new-runtime scaffolding converts the root module directory into a module source address by prefixing './' for relative paths and calling addrs.ParseModuleSource, which was designed for module block source arguments, not arbitrary filesystem paths (the comment in the code says exactly this). The error wraps a parse failure: the directory path contains characters that cannot be interpreted as a local source address, such as ':' (which makes the path look like a registry/remote address, including Windows drive letters), '?' or '#'.","triggerScenarios":"Absolute Windows paths (C:\\... do not start with ./ so they are parsed as remote addresses and rejected); directory names containing ':', '?', '#', or other address syntax; a root.SourceDir that is empty or degenerate after -chdir handling.","commonSituations":"Running the new-runtime-based commands (tofu test and similar) on Windows from drive-letter paths; checkouts under directories with unusual characters; odd -chdir arguments.","solutions":["Run the command from a path without ':', '?', '#' characters — on Windows, try invoking from a relative path so the './' prefix branch is used","Check the -chdir argument and current directory for stray address-like characters","Move or symlink the checkout into a plain path (e.g. C:\\src\\mod or ~/src/mod) and retry","If it fails on a clean POSIX path, report it — the code itself flags this path-to-address conversion as a stopgap"],"exampleFix":"# before (Windows absolute path is parsed as a remote address)\ntofu test -chdir C:\\proj\\mod\n\n# after\ncd C:\\proj\\mod && tofu test","handlingStrategy":"validation","validationCode":"abs, err := filepath.Abs(configDir)\nif err != nil {\n\treturn err\n}\nfor _, bad := range []string{\":\", \"?\", \"#\"} {\n\tif strings.Contains(abs, bad) {\n\t\t// ParseModuleSource would reject this as a non-local address\n\t\treturn fmt.Errorf(\"path %q contains %q and cannot be used as a local module source\", abs, bad)\n\t}\n}","typeGuard":null,"tryCatchPattern":"rootModuleSource, err := addrs.ParseModuleSource(configDir)\nif err != nil {\n\t// recover by retrying with a cleaned relative path from the module root\n\tif rel, relErr := filepath.Rel(moduleRoot, configDir); relErr == nil {\n\t\trootModuleSource, err = addrs.ParseModuleSource(\".\" + string(filepath.Separator) + rel)\n\t}\n\tif err != nil {\n\t\tdiags = diags.Append(fmt.Errorf(\"invalid root module source address: %w\", err))\n\t}\n}","preventionTips":["Invoke tofu from inside the module directory (relative configDir) so the ./-prefixed local path is used","Keep checkout paths free of ':', '?', '#' — especially on Windows drive-letter layouts","Avoid directory names that resemble registry or remote source addresses"],"tags":["go","opentofu","paths","windows","config"],"backgroundTag":null,"analyzedSha":"3561785c48c1ce615e7c50261bd351f26053efa2","analyzedAt":"2026-08-15T23:27:16.226Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}