{"record":{"id":"f575a9212ca50aa1","repo":"hashicorp/terraform","slug":"error-validating-destination-directory-s","errorCode":null,"errorMessage":"Error validating destination directory: %s","messagePattern":"Error validating destination directory: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/command/init_run.go","lineNumber":69,"sourceCode":"\t// Get the working directory\n\tpath := c.Meta.WorkingDir.RootModuleDir()\n\n\tif err := c.storePluginPath(c.pluginPath); err != nil {\n\t\tdiags = diags.Append(fmt.Errorf(\"Error saving -plugin-dir to workspace directory: %s\", err))\n\t\tview.Diagnostics(diags)\n\t\treturn 1\n\t}\n\n\t// Initialization can be aborted by interruption signals\n\tctx, done := c.InterruptibleContext(c.CommandContext())\n\tdefer done()\n\n\tif initArgs.FromModule != \"\" {\n\t\tsrc := initArgs.FromModule\n\n\t\tempty, err := configs.IsEmptyDir(path, initArgs.TestsDirectory)\n\t\tif err != nil {\n\t\t\tdiags = diags.Append(fmt.Errorf(\"Error validating destination directory: %s\", err))\n\t\t\tview.Diagnostics(diags)\n\t\t\treturn 1\n\t\t}\n\t\tif !empty {\n\t\t\tdiags = diags.Append(errors.New(strings.TrimSpace(errInitCopyNotEmpty)))\n\t\t\tview.Diagnostics(diags)\n\t\t\treturn 1\n\t\t}\n\n\t\tview.Output(views.CopyingConfigurationMessage, src)\n\n\t\thooks := uiModuleInstallHooks{\n\t\t\tUi:             c.Ui,\n\t\t\tShowLocalPaths: false, // since they are in a weird location for init\n\t\t\tView:           view,\n\t\t}\n\n\t\tctx, span := tracer.Start(ctx, \"-from-module=...\", trace.WithAttributes(","sourceCodeStart":51,"sourceCodeEnd":87,"githubUrl":"https://github.com/hashicorp/terraform/blob/c9def3e214014c1188faabfc4a5bde5095139765/internal/command/init_run.go#L51-L87","documentation":"Emitted by InitCommand.run in the -from-module branch when configs.IsEmptyDir(path, testsDir) returns an error (init_run.go:67-69). IsEmptyDir walks the target directory to confirm it is empty before copying the module source into it; any failure to stat/read that directory produces this message with the underlying error.","triggerScenarios":"Running `terraform init -from-module=<source>` into a target directory that exists but cannot be read or stat'd: permission denied on the directory or one of its entries, an I/O error from the filesystem, or a symlink loop inside the target dir.","commonSituations":"Re-initializing into a directory with restrictive permissions; target dir created by a different user/UID; failing disk; container bind-mount with incorrect ownership; leftover broken symlinks from a prior tool run.","solutions":["Check permissions/ownership of the target directory: `ls -la <dir>` and fix with chmod/chown.","Remove broken symlinks inside the target: `find <dir> -xtype l -delete`.","If the directory is not needed, delete it and let init recreate it: `rm -rf <dir> && terraform init -from-module=...`.","Verify the underlying filesystem/mount is healthy and readable."],"exampleFix":"# before\n$ terraform init -from-module=git::ssh://...  # target dir unreadable\n# after\n$ chmod a+rx ./target && terraform init -from-module=git::ssh://... ./target","handlingStrategy":"validation","validationCode":"// Before -from-module, confirm the destination is an empty, readable dir.\nif entries, err := os.ReadDir(dest); err != nil {\n    return fmt.Errorf(\"destination %q unreadable: %w\", dest, err)\n} else if len(entries) != 0 {\n    return fmt.Errorf(\"destination %q is not empty\", dest)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Point -from-module at a fresh, empty, writable directory.","Ensure the destination directory has read+execute+write for the terraform user.","Clean broken symlinks and stale .terraform before re-using a directory."],"tags":["terraform-init","from-module","filesystem","permissions"],"analyzedSha":"c9def3e214014c1188faabfc4a5bde5095139765","analyzedAt":"2026-08-07T15:39:49.278Z","schemaVersion":2},"datasetVersion":"2026-08-07T21:17:07.882Z"}