linshenkx/prompt-optimizer · error · StorageError
Failed to perform simple update: ${key}
Error message
Failed to perform simple update: ${key} What it means
StorageError with code 'write' thrown by _performSimpleUpdate — the non-transactional fallback path used when the atomic/transactional update fails. It means even the plain put() of the newly computed value rejected, so both the transactional and degraded write paths failed.
Source
Thrown at packages/core/src/services/storage/dexieStorageProvider.ts:267
try {
// 读取当前值
const currentRecord = await this.db.storage.get(key);
const currentValue = currentRecord?.value
? JSON.parse(currentRecord.value) as T
: null;
// 应用更新函数
const newValue = updateFn(currentValue);
// 直接写入新值(不使用事务)
await this.db.storage.put({
key,
value: JSON.stringify(newValue),
timestamp: Date.now()
});
} catch (error) {
console.error(`Simple update failed (${key}):`, error);
throw new StorageError(`Failed to perform simple update: ${key}`, 'write');
}
}
/**
* 执行原子更新
*/
private async _performAtomicUpdate<T>(
key: string,
updateFn: (currentValue: T | null) => T
): Promise<void> {
try {
// 使用更安全的事务处理方式
await this.db.transaction('rw', this.db.storage, async (tx) => {
try {
// 读取当前值
const currentRecord = await tx.table('storage').get(key);
const currentValue = currentRecord?.value
? JSON.parse(currentRecord.value) as TView on GitHub (pinned to 3e677b1d9f)
Solutions
- Inspect the logged 'Simple update failed (key):' line for the root cause
- If quota: evict data or reduce write size/frequency
- Ensure the database is open and the schema includes the key's table before issuing updates
Example fix
// before
await provider.update(key, fn);
// after
try { await provider.update(key, fn); }
catch (e) {
if (e instanceof StorageError && e.message.includes('simple update')) {
await freeSpace(); await provider.update(key, fn); // retry after eviction
} else throw e;
} Defensive patterns
Strategy: fallback
Validate before calling
const size = new Blob([JSON.stringify(value)]).size; if (size > 2_000_000) await trimBeforeWrite(key);
Type guard
const isSimpleUpdateError = (e: unknown): e is StorageError => e instanceof StorageError && /simple update/i.test(String((e as Error).message));
Try / catch
try { await provider.update(key, fn); } catch (e) { if (isSimpleUpdateError(e)) { await freeSpace(); const cur = JSON.parse((await provider.getItem(key)) ?? 'null'); await provider.setItem(key, fn(cur)); } else throw e; } Prevention
- Monitor quota and evict before writes fail
- Ensure db is open before updates; avoid update() during shutdown
- Watch the 'Simple update failed (key)' console line for the root cause
When it happens
Trigger: update() degrades to _performSimpleUpdate (e.g., after PrematureCommitError or unsupported transaction) and the subsequent db.storage.put of the serialized value rejects — quota exceeded, DB closed, or non-serializable state.
Common situations: Quota exhaustion while persisting frequently-updated keys; DB closed mid-operation during shutdown; schema drift after app upgrade.
Related errors
AI-assisted analysis of linshenkx/prompt-optimizer@3e677b1d9f (2026-08-27).
Data as JSON: /api/errors/5095b9133e4bee15.
Report an issue: GitHub.