RocketChat/Rocket.Chat · error · Error

Unknown error

Error message

Unknown error

What it means

Thrown by getBuffer when FileUpload.getBuffer returns something that is not a Buffer instance. The upload store is expected to yield a Node Buffer for the file's bytes; any other shape (null, stream, corrupted/empty data) triggers a deliberately opaque 'Unknown error' because the bridge cannot expose store internals.

Source

Thrown at apps/meteor/app/apps/server/bridges/uploads.ts:39

	}

	protected async getById(id: string, appId: string): Promise<IUpload> {
		this.orch.debugLog(`The App ${appId} is getting the upload: "${id}"`);

		// #TODO: #AppsEngineTypes - Remove explicit types and typecasts once the apps-engine definition/implementation mismatch is fixed.
		const promise: Promise<IUpload | undefined> = this.orch.getConverters()?.get('uploads').convertById(id);
		return promise as Promise<IUpload>;
	}

	protected async getBuffer(upload: IUpload, appId: string): Promise<Buffer> {
		this.orch.debugLog(`The App ${appId} is getting the upload: "${upload.id}"`);

		const rocketChatUpload = this.orch.getConverters()?.get('uploads').convertToRocketChat(upload);

		const result = await FileUpload.getBuffer(rocketChatUpload);

		if (!(result instanceof Buffer)) {
			throw new Error('Unknown error');
		}

		return result;
	}

	protected async createUpload(details: IUploadDetails, buffer: Buffer, appId: string): Promise<IUpload> {
		this.orch.debugLog(`The App ${appId} is creating an upload "${details.name}"`);

		if (!details.userId && !details.visitorToken) {
			throw new Error('Missing user to perform the upload operation');
		}

		const fileStore = FileUpload.getStore('Uploads');

		details.type = determineFileType(buffer, details.name);

		const uploadedFile = await fileStore.insert(getUploadDetails(details), buffer);
		this.orch.debugLog(`The App ${appId} has created an upload`, uploadedFile);

View on GitHub (pinned to f9d3ec372b)

Solutions

  1. Confirm the upload id still resolves to a real file via getById before requesting its buffer.
  2. Verify the FileUpload store backend is healthy and the file is present on disk/storage.
  3. Catch the error and report to the user that the file could not be read.

Example fix

// before
const buf = await read.getUploadReader().getBufferById(id);

// after
const upload = await read.getUploadReader().getById(id);
if (!upload) {
  // upload no longer exists; bail
  return;
}
let buf;
try {
  buf = await read.getUploadReader().getBufferById(id);
} catch {
  // file store could not return bytes
  return;
}
Defensive patterns

Strategy: validation

Validate before calling

const upload = await read.getUploadReader().getById(id);
if (!upload) {
  throw new Error('Upload not found; cannot read buffer');
}

Type guard

import { Buffer } from 'buffer';
function isBuffer(val: unknown): val is Buffer {
  return Buffer.isBuffer(val);
}

Try / catch

try {
  const buf = await read.getUploadReader().getBufferById(id);
} catch (err) {
  if (err instanceof Error && err.message === 'Unknown error') {
    // file store could not return bytes — report to user
  } else {
    throw err;
  }
}

Prevention

When it happens

Trigger: App requests the byte buffer of an upload whose underlying file is missing from the store, corrupted, stored in a backend that did not return raw bytes, or whose retrieval returned an unexpected type.

Common situations: Upload was deleted from the file store but its metadata remains; misconfigured S3/GridFS/filesystem store returning an error object instead of bytes; upload older than a retention cleanup; storage backend migration left dangling files.

Related errors


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