{"record":{"id":"a8e82a2b92aa7c39","repo":"wavetermdev/waveterm","slug":"error-getting-file-w","errorCode":null,"errorMessage":"error getting file: %w","messagePattern":"error getting file: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/filestore/blockstore_cache.go","lineNumber":120,"sourceCode":"\tif entry.File != nil {\n\t\treturn nil\n\t}\n\tfile, err := entry.loadFileForRead(ctx)\n\tif err != nil {\n\t\treturn err\n\t}\n\tentry.File = file\n\treturn nil\n}\n\n// does not populate the cache entry, returns err if file does not exist\nfunc (entry *CacheEntry) loadFileForRead(ctx context.Context) (*WaveFile, error) {\n\tif entry.File != nil {\n\t\treturn entry.File, nil\n\t}\n\tfile, err := dbGetZoneFile(ctx, entry.ZoneId, entry.Name)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error getting file: %w\", err)\n\t}\n\tif file == nil {\n\t\treturn nil, fs.ErrNotExist\n\t}\n\treturn file, nil\n}\n\nfunc withLock(s *FileStore, zoneId string, name string, fn func(*CacheEntry) error) error {\n\tentry := s.getEntryAndPin(zoneId, name)\n\tdefer s.unpinEntryAndTryDelete(zoneId, name)\n\tentry.Lock.Lock()\n\tdefer entry.Lock.Unlock()\n\treturn fn(entry)\n}\n\nfunc withLockRtn[T any](s *FileStore, zoneId string, name string, fn func(*CacheEntry) (T, error)) (T, error) {\n\tvar rtnVal T\n\trtnErr := withLock(s, zoneId, name, func(entry *CacheEntry) error {","sourceCodeStart":102,"sourceCodeEnd":138,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/filestore/blockstore_cache.go#L102-L138","documentation":"loadFileForRead fetches the file's metadata record (WaveFile) from the DB via dbGetZoneFile. Any DB error is wrapped as 'error getting file: %w'; a successful query with no record yields fs.ErrNotExist instead, meaning the file was never created or was deleted.","triggerScenarios":"loadFileIntoCache or readAt on a zone:name whose metadata row cannot be read — DB connection failure, missing/corrupt table, or the wrapped inner error from dbGetZoneFile.","commonSituations":"Database not migrated/initialized; DB unreachable (network, wrong DSN); racing a DeleteFile so metadata disappears mid-operation; typo in zoneId/name surfacing as DB lookup anomalies.","solutions":["Check errors.Is(err, fs.ErrNotExist) to distinguish 'file missing' from a real DB failure and create the file if needed.","Verify DB connectivity and schema (migrations) for the filestore tables.","Inspect the wrapped cause with %w/errors.Unwrap to find the driver-level error."],"exampleFix":"// before\n_, data, err := fs.ReadAt(ctx, zone, name, 0, 1024)\nif err != nil { return err }\n// after\n_, data, err := fs.ReadAt(ctx, zone, name, 0, 1024)\nif errors.Is(err, fs.ErrNotExist) { return createFileThenRetry(ctx, zone, name) }\nif err != nil { return fmt.Errorf(\"read failed: %w\", err) }","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"_, data, err := fs.ReadAt(ctx, zone, name, 0, n)\nif errors.Is(err, fs.ErrNotExist) {\n    // file missing: create it or return not-found to caller\n} else if err != nil && strings.Contains(err.Error(), \"error getting file\") {\n    // DB failure: check connectivity/migrations, inspect errors.Unwrap(err)\n}","preventionTips":["Check errors.Is(err, fs.ErrNotExist) before treating it as a DB outage.","Run filestore DB migrations as part of startup.","Verify the file exists (stat) before read-heavy paths."],"tags":["filestore","database","cache"],"backgroundTag":"database-lookup-failed","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}