{"record":{"id":"9ec008338cd22311","repo":"n8n-io/n8n","slug":"failed-to-delete-errors-length-of-batch-lengt","errorCode":null,"errorMessage":"Failed to delete ${errors.length} of ${batch.length} objects: ${summary}","messagePattern":"Failed to delete (.+?) of (.+?) objects: (.+?)","errorType":"exception","errorClass":"UnexpectedError","httpStatus":null,"severity":"error","filePath":"packages/@n8n/blob-storage/src/object-store/object-store.service.ee.ts","lineNumber":301,"sourceCode":"\t\t\t\tthis.logger.debug('Sending DELETE MANY request to S3', {\n\t\t\t\t\tbucket: this.bucket,\n\t\t\t\t\tobjectCount: batch.length,\n\t\t\t\t});\n\n\t\t\t\t// `DeleteObjects` reports per-key failures in the response rather than failing the request\n\t\t\t\tconst { Errors: errors } = await this.s3Client.send(new DeleteObjectsCommand(params));\n\n\t\t\t\tif (errors && errors.length > 0) {\n\t\t\t\t\tthis.logger.error('Failed to delete objects from S3', {\n\t\t\t\t\t\tbucket: this.bucket,\n\t\t\t\t\t\tfailures: errors.map((e) => ({ key: e.Key, code: e.Code, message: e.Message })),\n\t\t\t\t\t});\n\n\t\t\t\t\tconst summary = errors\n\t\t\t\t\t\t.slice(0, MAX_REPORTED_DELETE_ERRORS)\n\t\t\t\t\t\t.map((e) => `${e.Key ?? '<unknown key>'} (${e.Code ?? '?'}: ${e.Message ?? '?'})`)\n\t\t\t\t\t\t.join(', ');\n\t\t\t\t\tthrow new UnexpectedError(\n\t\t\t\t\t\t`Failed to delete ${errors.length} of ${batch.length} objects: ${summary}`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (e) {\n\t\t\tthis.handleS3Error(e);\n\t\t}\n\t}\n\n\t/**\n\t * List objects with a common prefix in the configured bucket.\n\t */\n\tasync list(prefix: string) {\n\t\tconst items = [];\n\t\tlet isTruncated = true;\n\t\tlet continuationToken;\n\n\t\ttry {","sourceCodeStart":283,"sourceCodeEnd":319,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/blob-storage/src/object-store/object-store.service.ee.ts#L283-L319","documentation":"UnexpectedError thrown inside the S3 batch delete after DeleteObjectsCommand returns an Errors[] array. S3's bulk delete reports per-key failures inside a 200 response rather than failing the HTTP call, so the code inspects Errors and throws when any key failed. The message reports counts plus the first MAX_REPORTED_DELETE_ERRORS (5) failures with key/code/message.","triggerScenarios":"s3Client.send(new DeleteObjectsCommand({ Delete: { Objects: [...] } })) resolves with response.Errors non-empty. Common per-key codes: AccessDenied, NoSuchKey, or internal error on individual objects within the batch.","commonSituations":"Batch cleanup of execution data where some objects are already gone (NoSuchKey) or locked (Object Lock / WORM); an IAM policy that allows list but not delete on some keys; cross-account bucket where some prefixes are denied; S3 inventory lag.","solutions":["Read the embedded summary to identify which keys failed and with what code.","For AccessDenied, widen the IAM delete-object permission on the failing prefixes.","For NoSuchKey, treat as best-effort (idempotent delete) and suppress in cleanup paths.","Re-run the delete for the remaining failing keys after fixing permissions."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Pre-check IAM delete permission on a representative key before bulk delete\n// (operational check, not code in-process)","typeGuard":"import { UnexpectedError } from 'n8n-workflow';\nconst isPartialDeleteFailure = (e: unknown): boolean =>\n  e instanceof UnexpectedError && /Failed to delete \\d+ of \\d+ objects/.test(e.message);","tryCatchPattern":"try {\n  await objectStoreService.deleteBatch(keys);\n} catch (e) {\n  if (e instanceof UnexpectedError && /Failed to delete/.test(e.message)) {\n    // parse the summary, retry only keys not marked NoSuchKey, fix IAM for AccessDenied\n  }\n  throw e;\n}","preventionTips":["Scope IAM to allow s3:DeleteObject on all keys the service writes.","Treat NoSuchKey as idempotent success in cleanup paths and suppress it.","Keep batches small so partial failures are easier to re-drive."],"tags":["s3","blob-storage","batch-delete","iam","partial-failure"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}