{"record":{"id":"ca31297f005ae9e7","repo":"RocketChat/Rocket.Chat","slug":"the-current-import-operation-is-already-finished","errorCode":null,"errorMessage":"The current import operation is already finished.","messagePattern":"The current import operation is already finished\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/server/services/import/service.ts","lineNumber":108,"sourceCode":"\t\treturn {\n\t\t\tstate,\n\t\t\toperation,\n\t\t};\n\t}\n\n\tprivate assertsValidStateForNewData(operation: IImport | undefined): asserts operation is IImport {\n\t\tif (!operation?.valid) {\n\t\t\tthrow new Error('Import operation not initialized.');\n\t\t}\n\t\tconst state = this.getStateOfOperation(operation);\n\t\tswitch (state) {\n\t\t\tcase 'loading':\n\t\t\tcase 'importing':\n\t\t\t\tthrow new Error('The current import operation can not receive new data.');\n\t\t\tcase 'done':\n\t\t\tcase 'error':\n\t\t\tcase 'canceled':\n\t\t\t\tthrow new Error('The current import operation is already finished.');\n\t\t}\n\t}\n\n\tpublic async addUsers(users: Omit<IImportUser, '_id' | 'services' | 'customFields'>[]): Promise<void> {\n\t\tif (!users.length) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst operation = await Imports.findLastImport();\n\n\t\tthis.assertsValidStateForNewData(operation);\n\n\t\tconst defaultRoles = getNewUserRoles();\n\t\tconst userRoles = new Set<string>(defaultRoles);\n\t\tfor await (const user of users) {\n\t\t\tif (!user.emails?.some((value) => value) || !user.importIds?.some((value) => value)) {\n\t\t\t\tthrow new Error('Users are missing required data.');\n\t\t\t}","sourceCodeStart":90,"sourceCodeEnd":126,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/server/services/import/service.ts#L90-L126","documentation":"Thrown by assertsValidStateForNewData when the last import operation is in a terminal state: 'done', 'error' or 'canceled'. Once an import finishes (successfully or not), the operation record is closed and cannot receive new data; a fresh operation must be started instead.","triggerScenarios":"Calling addUsers(...) after run() completed with state 'done'; retrying an upload against an operation that ended in 'error'; adding data to an operation the user canceled.","commonSituations":"Retrying a failed import by re-uploading into the same operation instead of starting a new one; background jobs that keep feeding a completed migration; canceled imports leaving stale client state.","solutions":["Start a new import operation rather than reusing the finished one","Check operation.state before uploading and branch to the start flow when it is terminal","Clear client-side references to the old operation after completion"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"const op = await Imports.findLastImport();\nif (['done', 'error', 'canceled'].includes(op?.status ?? '')) {\n  throw new Error('operation finished; start a new import');\n}","typeGuard":"function isTerminalImportState(state: string | undefined): boolean {\n  return state === 'done' || state === 'error' || state === 'canceled';\n}","tryCatchPattern":null,"preventionTips":["Start a new operation for repeat imports instead of reusing finished ones","Clear UI state referencing an import once it reaches a terminal state"],"tags":["import","state-machine","lifecycle","rocket-chat"],"backgroundTag":"invalid-operation-state","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-08-22T04:17:13.399Z"}