{"record":{"id":"aedffbf3bfc03f93","repo":"wavetermdev/waveterm","slug":"error-getting-data-parts-w","errorCode":null,"errorMessage":"error getting data parts: %w","messagePattern":"error getting data parts: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/filestore/blockstore_cache.go","lineNumber":281,"sourceCode":"\tvar rtn []int\n\tfor _, partIdx := range parts {\n\t\tif dataEntries[partIdx] != nil {\n\t\t\tcontinue\n\t\t}\n\t\trtn = append(rtn, partIdx)\n\t}\n\treturn rtn\n}\n\nfunc (entry *CacheEntry) loadDataPartsIntoCache(ctx context.Context, parts []int) error {\n\tparts = prunePartsWithCache(entry.DataEntries, parts)\n\tif len(parts) == 0 {\n\t\t// parts are already loaded\n\t\treturn nil\n\t}\n\tdbDataParts, err := dbGetFileParts(ctx, entry.ZoneId, entry.Name, parts)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error getting data parts: %w\", err)\n\t}\n\tfor partIdx, dce := range dbDataParts {\n\t\tentry.DataEntries[partIdx] = dce\n\t}\n\treturn nil\n}\n\nfunc (entry *CacheEntry) loadDataPartsForRead(ctx context.Context, parts []int) (map[int]*DataCacheEntry, error) {\n\tif len(parts) == 0 {\n\t\treturn nil, nil\n\t}\n\tdbParts := prunePartsWithCache(entry.DataEntries, parts)\n\tvar dbDataParts map[int]*DataCacheEntry\n\tif len(dbParts) > 0 {\n\t\tvar err error\n\t\tdbDataParts, err = dbGetFileParts(ctx, entry.ZoneId, entry.Name, dbParts)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"error getting data parts: %w\", err)","sourceCodeStart":263,"sourceCodeEnd":299,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/filestore/blockstore_cache.go#L263-L299","documentation":"loadDataPartsIntoCache fetches the required data parts for an entry from the DB via dbGetFileParts. If that bulk lookup fails, the error is wrapped as 'error getting data parts: %w' and the entry's data cache is left partially unpopulated.","triggerScenarios":"WriteAt, ReadAt, or compaction paths that call loadDataPartsIntoCache with parts missing from the in-memory cache, when dbGetFileParts hits a DB error (connectivity, missing rows, query failure).","commonSituations":"Database restarts or network blips during reads/writes; DB schema drift or corruption so part rows are unreadable; very large part batches timing out.","solutions":["Unwrap the error to find the driver-level cause (connection, timeout, permissions).","Retry the operation once DB connectivity is restored; the parts lookup is idempotent.","Verify DB schema/migrations for the file-parts table and check part indices for corruption."],"exampleFix":"// before\n_, data, err := fs.ReadAt(ctx, zone, name, 0, size)\nif err != nil { return err }\n// after\n_, data, err := fs.ReadAt(ctx, zone, name, 0, size)\nif err != nil && strings.Contains(err.Error(), \"error getting data parts\") {\n    return retryWithBackoff(3, func() error { _, _, err = fs.ReadAt(ctx, zone, name, 0, size); return err })\n}","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"_, data, err := fs.ReadAt(ctx, zone, name, off, n)\nif err != nil && strings.Contains(err.Error(), \"error getting data parts\") {\n    return retryWithBackoff(3, time.Second, func() error {\n        _, data, err = fs.ReadAt(ctx, zone, name, off, n)\n        return err\n    })\n}","preventionTips":["Add retry with backoff for transient DB failures on part loads.","Monitor DB availability; part fetches fail hard when the DB is down.","Keep part-table schema migrations current to avoid lookup errors."],"tags":["filestore","database","parts"],"backgroundTag":"database-lookup-failed","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}