{"record":{"id":"cb6b6b1566d49660","repo":"hashicorp/terraform","slug":"cannot-read-directory-s","errorCode":null,"errorMessage":"Cannot read directory %s","messagePattern":"Cannot read directory (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/command/fmt.go","lineNumber":243,"sourceCode":"\t}\n\n\treturn diags\n}\n\nfunc (c *FmtCommand) processDir(path string, stdout io.Writer) tfdiags.Diagnostics {\n\tvar diags tfdiags.Diagnostics\n\n\tlog.Printf(\"[TRACE] terraform fmt: looking for files in %s\", path)\n\n\tentries, err := os.ReadDir(path)\n\tif err != nil {\n\t\tswitch {\n\t\tcase os.IsNotExist(err):\n\t\t\tdiags = diags.Append(fmt.Errorf(\"There is no configuration directory at %s\", path))\n\t\tdefault:\n\t\t\t// ReadDir does not produce error messages that are end-user-appropriate,\n\t\t\t// so we'll need to simplify here.\n\t\t\tdiags = diags.Append(fmt.Errorf(\"Cannot read directory %s\", path))\n\t\t}\n\t\treturn diags\n\t}\n\n\tfor _, info := range entries {\n\t\tname := info.Name()\n\t\tif configs.IsIgnoredFile(name) {\n\t\t\tcontinue\n\t\t}\n\t\tsubPath := filepath.Join(path, name)\n\t\tif info.IsDir() {\n\t\t\tif c.recursive {\n\t\t\t\tsubDiags := c.processDir(subPath, stdout)\n\t\t\t\tdiags = diags.Append(subDiags)\n\t\t\t}\n\n\t\t\t// We do not recurse into child directories by default because we\n\t\t\t// want to mimic the file-reading behavior of \"terraform plan\", etc,","sourceCodeStart":225,"sourceCodeEnd":261,"githubUrl":"https://github.com/hashicorp/terraform/blob/d32a084675427f5ac3f7d2868578ef8b2c1dc525/internal/command/fmt.go#L225-L261","documentation":"Thrown by processDir when os.ReadDir returns an error that is NOT os.IsNotExist — i.e., the directory exists but cannot be read. The generic OS error is deliberately simplified because raw ReadDir messages are not end-user-appropriate.","triggerScenarios":"The directory exists but the user lacks read/execute permission on it; the path is not a directory (e.g., a file passed where a dir was expected after stat); filesystem I/O error; SELinux/AppArmor denial.","commonSituations":"Permission denied (chmod 000 or owned by another user); a broken NFS mount; security policy blocking directory reads; a regular file mistaken for a directory.","solutions":["Check permissions on the directory: `ls -ld <path>` and ensure read+execute bits are set for the current user.","Run terraform as a user with access, or `chmod a+rx <dir>` if appropriate.","Confirm the path is actually a directory and the filesystem mount is healthy."],"exampleFix":"$ chmod a+rx modules/ && terraform fmt modules/","handlingStrategy":"validation","validationCode":"// Verify the directory is readable before fmt.\nfunc dirReadable(p string) bool {\n    f, err := os.Open(p)\n    if err != nil { return false }\n    f.Close()\n    return true\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Ensure read+execute permissions on module directories.","Run terraform as a user with directory access.","Confirm the path is a directory, not a file."],"tags":["terraform-fmt","filesystem","permissions","directory"],"backgroundTag":null,"analyzedSha":"d32a084675427f5ac3f7d2868578ef8b2c1dc525","analyzedAt":"2026-08-11T18:43:52.779Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}