{"record":{"id":"98518fcb474e12ec","repo":"hashicorp/terraform","slug":"failed-to-read-file-s","errorCode":null,"errorMessage":"Failed to read file %s","messagePattern":"Failed to read file (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"internal/command/fmt.go","lineNumber":146,"sourceCode":"\tfor _, path := range paths {\n\t\tpath = c.normalizePath(path)\n\t\tinfo, err := os.Stat(path)\n\t\tif err != nil {\n\t\t\tdiags = diags.Append(fmt.Errorf(\"No file or directory at %s\", path))\n\t\t\treturn diags\n\t\t}\n\t\tif info.IsDir() {\n\t\t\tdirDiags := c.processDir(path, stdout)\n\t\t\tdiags = diags.Append(dirDiags)\n\t\t} else {\n\t\t\tfmtd := false\n\t\t\tfor _, ext := range fmtSupportedExts {\n\t\t\t\tif strings.HasSuffix(path, ext) {\n\t\t\t\t\tf, err := os.Open(path)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t// Open does not produce error messages that are end-user-appropriate,\n\t\t\t\t\t\t// so we'll need to simplify here.\n\t\t\t\t\t\tdiags = diags.Append(fmt.Errorf(\"Failed to read file %s\", path))\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\n\t\t\t\t\tfileDiags := c.processFile(c.normalizePath(path), f, stdout, false)\n\t\t\t\t\tdiags = diags.Append(fileDiags)\n\t\t\t\t\tf.Close()\n\n\t\t\t\t\t// Take note that we processed the file.\n\t\t\t\t\tfmtd = true\n\n\t\t\t\t\t// Don't check the remaining extensions.\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif !fmtd {\n\t\t\t\tdiags = diags.Append(fmt.Errorf(\"Only .tf, .tfvars, and .tftest.hcl files can be processed with terraform fmt\"))\n\t\t\t\tcontinue","sourceCodeStart":128,"sourceCodeEnd":164,"githubUrl":"https://github.com/hashicorp/terraform/blob/c9def3e214014c1188faabfc4a5bde5095139765/internal/command/fmt.go#L128-L164","documentation":"Returned by FmtCommand.fmt (fmt.go:146) when os.Open fails for a file that matched a supported extension (so fmt tried to open it for formatting). Because the file already passed os.Stat (the outer loop), an Open failure here typically indicates a transient condition — the file disappeared between stat and open, or permission changed. The error is reported per-file and fmt continues to the next path.","triggerScenarios":"os.Open(path) returns an error between a successful os.Stat and the open: the file was deleted (race with another process), permission was revoked (chmod removed read bit), the file was renamed, or an external tool locked it (Windows).","commonSituations":"Another process (formatter, linter, sync client) deletes/recreates files while fmt runs; the file is a broken symlink; permissions changed mid-run; on Windows, an editor holds an exclusive lock; CI workspace cleanup racing with fmt.","solutions":["Re-run fmt after the racing process completes; the file likely exists again.","Check the file is readable: `ls -l <file>` and `cat <file> >/dev/null`; fix permissions (`chmod +r <file>`) if revoked.","Resolve broken symlinks: `readlink <file>` and point at the real target.","Exclude volatile directories (sync folders, build outputs) from fmt, or run fmt on a stable checkout."],"exampleFix":"# before\n$ terraform fmt main.tf\nFailed to read file main.tf   # file deleted or chmod'd mid-run\n\n# after\n$ ls -l main.tf               # confirm it is back and readable\n$ terraform fmt main.tf","handlingStrategy":"try-catch","validationCode":"// Pre-open the file and confirm readability\nf, err := os.Open(path)\nif err != nil {\n    return fmt.Errorf(\"cannot open %s for formatting: %w\", path, err)\n}\ndefer f.Close()\n// pass f to fmt","typeGuard":null,"tryCatchPattern":"// On a transient open failure, retry once; surface a per-file warning otherwise.\nfor attempt := 0; attempt < 2; attempt++ {\n    if err := formatOne(path); err == nil { break }\n    if attempt == 1 || !isTransient(err) { log.Printf(\"warning: skipped %s: %v\", path, err) }\n    time.Sleep(100 * time.Millisecond)\n}","preventionTips":["Avoid running fmt concurrently with tools that delete or rewrite config files.","Make config files readable by the Terraform process.","Run fmt on a stable checkout in CI, not a live workspace.","Resolve broken symlinks before formatting."],"tags":["cli","fmt","filesystem","race-condition","permissions"],"analyzedSha":"c9def3e214014c1188faabfc4a5bde5095139765","analyzedAt":"2026-08-07T15:39:49.278Z","schemaVersion":2},"datasetVersion":"2026-08-07T20:17:04.800Z"}