{"record":{"id":"79d3d4f2a50fad96","repo":"wavetermdev/waveterm","slug":"error-getting-file-v","errorCode":null,"errorMessage":"error getting file: %v","messagePattern":"error getting file: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/filestore/blockstore.go","lineNumber":184,"sourceCode":"\tfileNames, err := dbGetZoneFileNames(ctx, zoneId)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error getting zone files: %v\", err)\n\t}\n\tfor _, name := range fileNames {\n\t\ts.DeleteFile(ctx, zoneId, name)\n\t}\n\treturn nil\n}\n\n// if file doesn't exsit, returns fs.ErrNotExist\nfunc (s *FileStore) Stat(ctx context.Context, zoneId string, name string) (*WaveFile, error) {\n\treturn withLockRtn(s, zoneId, name, func(entry *CacheEntry) (*WaveFile, error) {\n\t\tfile, err := entry.loadFileForRead(ctx)\n\t\tif err != nil {\n\t\t\tif err == fs.ErrNotExist {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\treturn nil, fmt.Errorf(\"error getting file: %v\", err)\n\t\t}\n\t\treturn file.DeepCopy(), nil\n\t})\n}\n\nfunc (s *FileStore) ListFiles(ctx context.Context, zoneId string) ([]*WaveFile, error) {\n\tfiles, err := dbGetZoneFiles(ctx, zoneId)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error getting zone files: %v\", err)\n\t}\n\tfor idx, file := range files {\n\t\twithLock(s, file.ZoneId, file.Name, func(entry *CacheEntry) error {\n\t\t\tif entry.File != nil {\n\t\t\t\tfiles[idx] = entry.File.DeepCopy()\n\t\t\t}\n\t\t\treturn nil\n\t\t})\n\t}","sourceCodeStart":166,"sourceCodeEnd":202,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/filestore/blockstore.go#L166-L202","documentation":"GetFile loads the WaveFile for read via entry.loadFileForRead inside a read lock. A fs.ErrNotExist is passed through untouched (the normal 'file not found' case), but any other load failure is wrapped as 'error getting file: %v'. This separates genuine absence from real I/O or storage failures.","triggerScenarios":"entry.loadFileForRead returns a non-ErrNotExist error: the backing DB read of file metadata fails, a cache/state inconsistency occurs while materializing the file, the context is cancelled mid-load, or the stored record is corrupt.","commonSituations":"Underlying store closed or failing while a file is opened; context timeouts on slow storage; a file record partially deleted or corrupted so metadata loads fail; concurrent operations leaving cache entries inconsistent.","solutions":["First distinguish absence from failure: check errors.Is(err, fs.ErrNotExist) and handle that as 'file missing', not an error path.","Inspect the wrapped cause (%v) for the real storage error; retry transient DB failures.","Ensure the store and DB are healthy and open; re-open/reinitialize if closed.","Check context deadlines/cancellation on the read path and use an adequate timeout."],"exampleFix":"// before\nfile, err := store.GetFile(ctx, zoneId, name)\nif err != nil {\n\treturn err\n}\n// after\nfile, err := store.GetFile(ctx, zoneId, name)\nif err != nil {\n\tif errors.Is(err, fs.ErrNotExist) {\n\t\treturn createNewFile(ctx, zoneId, name)\n\t}\n\treturn fmt.Errorf(\"get file %s/%s: %w\", zoneId, name, err)\n}","handlingStrategy":"try-catch","validationCode":"// distinguish absence from failure after the call; pre-check context\nif ctx.Err() != nil { return ctx.Err() }","typeGuard":"func isNotExist(err error) bool { return errors.Is(err, fs.ErrNotExist) }","tryCatchPattern":"file, err := store.GetFile(ctx, zoneId, name)\nif err != nil {\n\tif isNotExist(err) {\n\t\t// benign: file does not exist\n\t\treturn nil\n\t}\n\tif strings.Contains(err.Error(), \"error getting file:\") {\n\t\t// storage failure: retry or surface\n\t\treturn fmt.Errorf(\"get %s/%s: %w\", zoneId, name, err)\n\t}\n\treturn err\n}","preventionTips":["Always check errors.Is(err, fs.ErrNotExist) before treating the error as fatal.","Pass contexts with adequate deadlines for storage reads.","Keep the backing DB healthy; monitor wrapped causes.","Handle missing files with a create-or-fallback path instead of failing."],"tags":["database","filestore","io"],"backgroundTag":"file-read-failed","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}