{"record":{"id":"a8c05323b58eb258","repo":"larksuite/cli","slug":"cannot-stat-opened-file-w","errorCode":null,"errorMessage":"cannot stat opened file: %w","messagePattern":"cannot stat opened file: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/vfs/localfileio/openvalidated_unix.go","lineNumber":61,"sourceCode":"\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif err := inspectOpenedFile(f, pre, true); err != nil {\n\t\tf.Close()\n\t\t// An unusable target is a bad argument, not an internal fault: callers\n\t\t// map ErrPathValidation to a typed validation error, and the fd checks\n\t\t// are the same verdict the path checks make, one layer later.\n\t\treturn nil, &fileio.PathValidationError{Err: err}\n\t}\n\treturn f, nil\n}\n\n// inspectOpenedFile validates the opened fd and restores blocking mode. pre is\n// nil when there is no prior Stat to compare against.\nfunc inspectOpenedFile(f *os.File, pre os.FileInfo, rejectHardLinks bool) error {\n\tpost, err := f.Stat()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"cannot stat opened file: %w\", err)\n\t}\n\tif pre != nil && !os.SameFile(pre, post) {\n\t\treturn fmt.Errorf(\"file changed between validation and open\")\n\t}\n\tif !post.Mode().IsRegular() {\n\t\treturn fmt.Errorf(\"not a regular file (directories, devices, FIFOs, and sockets are refused)\")\n\t}\n\tif rejectHardLinks {\n\t\tif st, ok := post.Sys().(*syscall.Stat_t); ok && st.Nlink > 1 {\n\t\t\treturn fmt.Errorf(\"file has multiple hard links, so the other names it can be reached by \" +\n\t\t\t\t\"cannot be checked (hint: copy the file and use the copy instead)\")\n\t\t}\n\t}\n\tif err := syscall.SetNonblock(int(f.Fd()), false); err != nil {\n\t\treturn fmt.Errorf(\"cannot restore blocking mode: %w\", err)\n\t}\n\treturn nil\n}","sourceCodeStart":43,"sourceCodeEnd":79,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/internal/vfs/localfileio/openvalidated_unix.go#L43-L79","documentation":"inspectOpenedFile could not f.Stat() the freshly opened descriptor. The library stats the fd after open to verify it matches the pre-open validation, so if that fstat fails it cannot confirm the file is safe and refuses it. This is an OS-level fstat failure on an already-open fd, so it is rare.","triggerScenarios":"f.Stat() on the *os.File returned by vfs.OpenFile fails after the open succeeded — e.g. the fd was closed concurrently, the file was deleted on a filesystem where the inode vanished mid-call, or an fd/resource limit (EMFILE/ENFILE) hit at fstat time.","commonSituations":"Concurrent code closing the same *os.File; process hitting RLIMIT_NOFILE; exotic filesystems (FUSE/network mounts) returning EIO on fstat.","solutions":["Check for concurrent Close of the *os.File in your code between OpenFile and use","Raise the file-descriptor limit (ulimit -n) if EMFILE/ENFILE appears","Check the wrapped errno (%w cause) for EIO — verify the underlying filesystem mount is healthy","Retry the operation; a transient fstat failure is not a path-policy rejection"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"if info, err := os.Stat(path); err != nil { return fmt.Errorf(\"target unavailable before open: %w\", err) }","typeGuard":null,"tryCatchPattern":"var pve *fileio.PathValidationError\nif errors.As(err, &pve) { /* validation-class failure; inspect pve.Unwrap() errno */ } else if err != nil { /* transport/other */ }","preventionTips":["Never share *os.File across goroutines that Close","Keep RLIMIT_NOFILE comfortably above your open-file count","Inspect the wrapped errno (errors.Unwrap / errors.As) to distinguish EIO from fd exhaustion"],"tags":["filesystem","fstat","unix"],"backgroundTag":"fstat-failed","analyzedSha":"7fd6ef3c07182257ce776cdc5a614e122d5bd4b3","analyzedAt":"2026-09-04T21:17:44.649Z","contentChangedAt":"2026-09-04T21:17:44.649Z","schemaVersion":2},"datasetVersion":"2026-09-12T02:17:10.037Z"}