{"record":{"id":"98ab7cf9b45ed8f6","repo":"HeyPuter/puter","slug":"failed-to-resolve-prepared-batch-item-for-index","errorCode":null,"errorMessage":"Failed to resolve prepared batch item for index ${index}","messagePattern":"Failed to resolve prepared batch item for index (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/backend/controllers/fs/FSController.ts","lineNumber":884,"sourceCode":"                fileMetadata: requestBody.fileMetadata,\n                thumbnailData: requestBody.thumbnailData,\n                guiMetadata: requestBody.guiMetadata,\n            })),\n            storageAllowanceMax,\n        );\n        await this.services.fs.assertStorageAllowanceForPreparedBatch(\n            preparedBatch,\n            undefined,\n            storageAllowanceMax,\n        );\n\n        const uploadResults = await runWithConcurrencyLimitSettled(\n            filteredRequests,\n            8,\n            async (requestBody, index) => {\n                const preparedItem = preparedBatch.items[index];\n                if (!preparedItem) {\n                    throw new Error(\n                        `Failed to resolve prepared batch item for index ${index}`,\n                    );\n                }\n                const uploadTracker = await this.#createUploadTracker(\n                    userId,\n                    preparedItem.objectKey,\n                    preparedItem.normalizedInput.path,\n                    preparedItem.normalizedInput.size,\n                    requestBody.guiMetadata,\n                );\n                return this.services.fs.uploadPreparedBatchItem({\n                    preparedBatch,\n                    itemIndex: preparedItem.index,\n                    fileContent: requestBody.fileContent,\n                    encoding: requestBody.encoding,\n                    uploadTracker,\n                });\n            },","sourceCodeStart":866,"sourceCodeEnd":902,"githubUrl":"https://github.com/HeyPuter/puter/blob/908ec23eda38526170322c3edf71ba45ecb1ca95/src/backend/controllers/fs/FSController.ts#L866-L902","documentation":"Thrown inside the JSON-body /fs/batchWrite path (non-multipart) when a prepared batch item is missing at a given array index during the concurrency-limited upload loop. Prepared via prepareBatchWrites from filteredRequests, so the items array should align 1:1 with filteredRequests. A missing item means the prepared batch has fewer entries than the request list — an internal invariant violation.","triggerScenarios":"Not triggerable by a well-formed client request; preparedBatch.items should match filteredRequests.length. Would fire if prepareBatchWrites filters or reorders items differently from the controller's filteredRequests, or if a future edit changes the indexing contract. Thrown as a plain Error (not HttpError), so it surfaces as a 500.","commonSituations":"Encountered after edits to prepareBatchWrites that drop items or change array length. A mismatch between controller-side path filtering (#shouldIgnoreUploadPath) and service-side filtering.","solutions":["Treat as a server bug; report with the request body shape and item count.","Inspect FSService.prepareBatchWrites to confirm it returns items.length === input.length.","Retry once in case of transient state, then escalate if it reproduces."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"async function robustJsonBatch(reqs, attempts = 2) {\n  for (let i = 0; i < attempts; i++) {\n    try { return await batchWrite(reqs); }\n    catch (e) { if (/Failed to resolve prepared batch item/.test(e?.message ?? '') && i < attempts - 1) continue; throw e; }\n  }\n}","preventionTips":["Treat as a server invariant bug; report with the request body shape.","Retry once for transient backend state."],"tags":["fs","batch-write","internal-error","invariant"],"backgroundTag":null,"analyzedSha":"908ec23eda38526170322c3edf71ba45ecb1ca95","analyzedAt":"2026-08-12T20:53:15.911Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}