RocketChat/Rocket.Chat · error · Error

Not implemented.

Error message

Not implemented.

What it means

Thrown unconditionally by AppPersistenceBridge.update after the data-type guard passes. The method is a deliberate stub: update-by-id is not implemented in the Rocket.Chat Apps Engine persistence bridge. Apps that need to mutate persisted data must use updateByAssociations (which performs a real Mongo update with $set) or remove + create. The throw exists so callers fail loudly rather than silently no-op.

Source

Thrown at apps/meteor/app/apps/server/bridges/persistence.ts:113

		const records = await this.orch.getPersistenceModel().find(query).toArray();

		if (!records?.length) {
			return undefined;
		}

		await this.orch.getPersistenceModel().remove(query);

		return Array.isArray(records) ? records.map((r) => r.data) : [];
	}

	protected async update(id: string, data: object, _upsert: boolean, appId: string): Promise<string> {
		this.orch.debugLog(`The App ${appId} is updating the record "${id}"`);

		if (typeof data !== 'object') {
			throw new Error('Attempted to store an invalid data type, it must be an object.');
		}

		throw new Error('Not implemented.');
	}

	protected async updateByAssociations(
		associations: Array<RocketChatAssociationRecord>,
		data: object,
		upsert = true,
		appId: string,
	): Promise<string> {
		this.orch.debugLog({ msg: `The App ${appId} is updating the record with association to data as follows:`, associations });

		if (typeof data !== 'object') {
			throw new Error('Attempted to store an invalid data type, it must be an object.');
		}

		const query = {
			appId,
			associations,
		};

View on GitHub (pinned to f9d3ec372b)

Solutions

  1. Replace update(id, data) with updateByAssociations(associations, data, true) keyed by an association you control (e.g. a unique record id association).
  2. Implement update as: read the existing record by id, remove it, then createWithAssociations with the same associations and the new data.
  3. Track and store an association alongside every create so updateByAssociations is always available as the update path.

Example fix

// before
await persistence.update(recordId, newData, true, appId);

// after
const idAssoc = { id: recordId };
await persistence.updateByAssociations([idAssoc], newData, true, appId);
Defensive patterns

Strategy: fallback

Validate before calling

// persistence.update is not implemented — use associations instead.
// Always pair a record with an association at create time:
const idAssoc = RocketChatAssociationRecord.MINE; // or a custom record id association
await persistence.createWithAssociations(data, [idAssoc], appId);
// later:
await persistence.updateByAssociations([idAssoc], newData, true, appId);

Prevention

When it happens

Trigger: Any App that calls the persistence accessor's update(id, data, upsert) method with a valid object payload will hit this regardless of arguments.

Common situations: Apps written against older documentation that described update-by-id; code ported from another persistence library; IDE autocomplete leading the developer to the stubbed method.

Related errors


AI-assisted analysis of RocketChat/Rocket.Chat@f9d3ec372b (2026-08-12). Data as JSON: /api/errors/ea7d546c0c62ecb9. Report an issue: GitHub.