{"record":{"id":"578243aab55212bd","repo":"grpc-ecosystem/grpc-gateway","slug":"read-s-w","errorCode":null,"errorMessage":"read %s: %w","messagePattern":"read (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"openapiv3-merge/main.go","lineNumber":46,"sourceCode":"\nfunc main() {\n\tif err := run(os.Args[1:], os.Stdout); err != nil {\n\t\tfmt.Fprintln(os.Stderr, \"openapiv3-merge:\", err)\n\t\tos.Exit(1)\n\t}\n}\n\n// run is the testable entry point. It accepts the program's arguments (no\n// program name) and the writer to emit the merged document to.\nfunc run(args []string, out io.Writer) error {\n\tif len(args) == 0 {\n\t\treturn errors.New(\"usage: openapiv3-merge FILE [FILE ...]\")\n\t}\n\tinputs := make([]merge.Input, 0, len(args))\n\tfor _, path := range args {\n\t\tdata, err := os.ReadFile(path)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"read %s: %w\", path, err)\n\t\t}\n\t\tinputs = append(inputs, merge.Input{Name: path, Data: data})\n\t}\n\tmerged, err := merge.Merge(inputs)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif _, err := out.Write(merged); err != nil {\n\t\treturn err\n\t}\n\tif _, err := io.WriteString(out, \"\\n\"); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n","sourceCodeStart":28,"sourceCodeEnd":62,"githubUrl":"https://github.com/grpc-ecosystem/grpc-gateway/blob/a58a4436a376a4bcc7d8f10c4d4f919a8438bba9/openapiv3-merge/main.go#L28-L62","documentation":"run reads each input file with os.ReadFile and wraps any OS-level read failure as `read <path>: <underlying error>`. This is the standard go idiom for file I/O errors: the wrapped error preserves the exact cause (file not found, permission denied, is a directory, etc.) while naming the path that failed.","triggerScenarios":"Invoking `openapiv3-merge FILE...` with a path that does not exist (ENOENT), is unreadable due to permissions (EACCES), is a directory, or otherwise fails os.ReadFile. Also triggered by tests calling run with a missing file path.","commonSituations":"Typo in the filename or wrong working directory; running inside a container where the spec file was not mounted; the spec file moved after code generation; running in CI where artifacts are in a different path; permission-restricted files.","solutions":["Check the path with `ls -l <path>`; fix typos and run from the correct working directory","If the error is permission denied, adjust file permissions or run with appropriate access","Confirm the file exists inside the container/CI environment (mount volumes, copy artifacts)","Verify you pass file paths, not directory paths","Use absolute paths or paths relative to the actual CWD"],"exampleFix":"// before\nopenapiv3-merge ./specs/api.jsoin\n// after\nopenapiv3-merge ./specs/api.json","handlingStrategy":"try-catch","validationCode":"for _, path := range args {\n    info, err := os.Stat(path)\n    if err != nil {\n        return fmt.Errorf(\"input %s is not accessible: %w\", path, err)\n    }\n    if info.IsDir() {\n        return fmt.Errorf(\"input %s is a directory, expected a file\", path)\n    }\n}","typeGuard":null,"tryCatchPattern":"if err := run(os.Args[1:]); err != nil {\n    var pathErr *fs.PathError\n    if errors.As(err, &pathErr) && errors.Is(pathErr.Err, fs.ErrNotExist) {\n        fmt.Fprintf(os.Stderr, \"file not found: %s\\n\", pathErr.Path)\n        os.Exit(1)\n    }\n    if errors.As(err, &pathErr) && errors.Is(pathErr.Err, fs.ErrPermission) {\n        fmt.Fprintf(os.Stderr, \"permission denied: %s\\n\", pathErr.Path)\n        os.Exit(1)\n    }\n    fmt.Fprintln(os.Stderr, err)\n    os.Exit(1)\n}","preventionTips":["Run the CLI from the directory containing the spec files or use absolute paths","Stat each input path before invoking the merge","In containers/CI, verify spec files are mounted/copied into the workspace","Distinguish file paths from directories in argument handling","Tab-complete paths to avoid typos"],"tags":["go","filesystem","cli","file-not-found"],"backgroundTag":"file-not-found","analyzedSha":"a58a4436a376a4bcc7d8f10c4d4f919a8438bba9","analyzedAt":"2026-09-02T10:28:31.537Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T16:17:10.729Z"}