{"record":{"id":"ea7d546c0c62ecb9","repo":"RocketChat/Rocket.Chat","slug":"not-implemented","errorCode":null,"errorMessage":"Not implemented.","messagePattern":"Not implemented\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"apps/meteor/app/apps/server/bridges/persistence.ts","lineNumber":113,"sourceCode":"\t\tconst records = await this.orch.getPersistenceModel().find(query).toArray();\n\n\t\tif (!records?.length) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tawait this.orch.getPersistenceModel().remove(query);\n\n\t\treturn Array.isArray(records) ? records.map((r) => r.data) : [];\n\t}\n\n\tprotected async update(id: string, data: object, _upsert: boolean, appId: string): Promise<string> {\n\t\tthis.orch.debugLog(`The App ${appId} is updating the record \"${id}\"`);\n\n\t\tif (typeof data !== 'object') {\n\t\t\tthrow new Error('Attempted to store an invalid data type, it must be an object.');\n\t\t}\n\n\t\tthrow new Error('Not implemented.');\n\t}\n\n\tprotected async updateByAssociations(\n\t\tassociations: Array<RocketChatAssociationRecord>,\n\t\tdata: object,\n\t\tupsert = true,\n\t\tappId: string,\n\t): Promise<string> {\n\t\tthis.orch.debugLog({ msg: `The App ${appId} is updating the record with association to data as follows:`, associations });\n\n\t\tif (typeof data !== 'object') {\n\t\t\tthrow new Error('Attempted to store an invalid data type, it must be an object.');\n\t\t}\n\n\t\tconst query = {\n\t\t\tappId,\n\t\t\tassociations,\n\t\t};","sourceCodeStart":95,"sourceCodeEnd":131,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/app/apps/server/bridges/persistence.ts#L95-L131","documentation":"AppPersistenceBridge.update(id, data, upsert, appId) is a stub in the Meteor implementation: after the object-type guard it unconditionally throws 'Not implemented.'. Updating a persistence record by its raw document id is simply not supported by the server bridge — only association-based writes (createWithAssociations / updateByAssociations) are implemented.","triggerScenarios":"Any app code path that ends in the bridge's update(): e.g. calling apps-engine persistence update-by-id helpers, or storing with create() and then trying to modify the record using the returned id.","commonSituations":"Developers assuming CRUD symmetry (create/read/update/delete by id); porting examples that predate the association-based API; refactoring away from associations to raw ids.","solutions":["Use updateByAssociations(associations, data, upsert) — it is implemented and upserts","Always create records with createWithAssociations so you can update them later by the same associations","Alternatively emulate update: read by id, remove, then re-create with associations","Never persist state whose only handle is the create()-returned Mongo id"],"exampleFix":"// before\nconst id = await app.getPersistence().create(data);\nawait persistenceUpdateById(id, newData); // bridge throws Not implemented.\n// after\nconst assoc = [ RocketChatAssociationRecord.MINE ];\nawait app.getPersistence().createWithAssociations(data, assoc);\nawait app.getPersistence().updateByAssociations(assoc, newData, true); // upsert supported","handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  await persistenceUpdateById(id, newData);\n} catch (err) {\n  if (err instanceof Error && err.message === 'Not implemented.') {\n    // fall back to the supported association-based upsert\n    await app.getPersistence().updateByAssociations(associations, newData, true);\n    return;\n  }\n  throw err;\n}","preventionTips":["Never design storage around the create()-returned Mongo id — use associations from the start","Standardize on createWithAssociations + updateByAssociations pairs in your persistence layer","If you must key by id: readById, remove, then createWithAssociations the new data","Watch apps-engine release notes if an update-by-id implementation ever lands"],"tags":["apps-engine","persistence","not-implemented","api-limitation"],"backgroundTag":"api-not-implemented","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","contentChangedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}