Skip to content

Commit 9d9186e

Browse files
committed
fix(storage): settle copilot accounting before deleting the blob
Address Cursor review: the blob was removed before releaseDeletedFileStorage, so a release failure left the counter inflated and the metadata active with the blob gone. Now the atomic soft-delete + decrement runs first and the blob is deleted only if it succeeds, so a failure leaves the file fully intact and retryable.
1 parent b9ac77e commit 9d9186e

1 file changed

Lines changed: 13 additions & 8 deletions

File tree

apps/sim/lib/uploads/contexts/copilot/copilot-file-manager.ts

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -249,18 +249,16 @@ export async function generateCopilotDownloadUrl(
249249
* @param key File storage key
250250
*/
251251
export async function deleteCopilotFile(key: string): Promise<void> {
252-
// Storage accounting is best-effort: reading metadata must never prevent the
253-
// file delete (the primary operation).
254252
const metadata = await getFileMetadataByKey(key, 'copilot').catch((error) => {
255253
logger.error('Failed to read copilot file metadata for storage accounting:', error)
256254
return null
257255
})
258256

259-
await deleteFile({
260-
key,
261-
context: 'copilot',
262-
})
263-
257+
// Settle storage accounting (atomic metadata soft-delete + quota decrement)
258+
// BEFORE removing the blob. If it fails, the file is left fully intact — blob,
259+
// active metadata, and counter all consistent — so a retry can re-run cleanly,
260+
// rather than orphaning the blob with a permanently inflated counter.
261+
let released = true
264262
if (metadata) {
265263
try {
266264
await releaseDeletedFileStorage(
@@ -270,9 +268,16 @@ export async function deleteCopilotFile(key: string): Promise<void> {
270268
metadata.workspaceId ?? undefined
271269
)
272270
} catch (storageError) {
271+
released = false
273272
logger.error('Failed to release copilot file storage:', storageError)
274273
}
275274
}
276275

277-
logger.info(`Successfully deleted copilot file: ${key}`)
276+
if (released) {
277+
await deleteFile({
278+
key,
279+
context: 'copilot',
280+
})
281+
logger.info(`Successfully deleted copilot file: ${key}`)
282+
}
278283
}

0 commit comments

Comments
 (0)