RocketChat/Rocket.Chat · error · Meteor.Error

invalid-file

invalid-file

Error message

File is not valid

What it means

After resolving a valid store, ufsComplete loads the file metadata document via store.getCollection().findOne({_id: fileId}); no document means Meteor.Error 'invalid-file' ('File is not valid'). The _id passed must exist in that store's collection (rocketchat_uploads for the Uploads store) — the upload record is created when the upload starts, so a missing record means the upload never started, was deleted, or belongs to a different store.

Source

Thrown at apps/meteor/server/ufs/ufs-methods.ts:35

		throw new Meteor.Error('invalid-store', 'Store not found');
	}

	const tmpFile = UploadFS.getTempFilePath(fileId);

	const removeTempFile = () =>
		fs.promises.unlink(tmpFile).catch(() => {
			console.warn(`[ufsComplete] Failed to remove temp file: ${tmpFile}`);
		});

	return new Promise(async (resolve, reject) => {
		try {
			// todo check if temp file exists

			// Get file
			const file = await store.getCollection().findOne<IUpload>({ _id: fileId }, { session: options?.session });

			if (!file) {
				throw new Meteor.Error('invalid-file', 'File is not valid');
			}

			// Validate file before moving to the store
			await store.validate(file, { session: options?.session });

			// Get the temp file
			const rs = fs.createReadStream(tmpFile, {
				flags: 'r',
				encoding: undefined,
				autoClose: true,
			});

			// Clean upload if error occurs
			rs.on('error', (err) => {
				console.error(err);
				void store.removeById(fileId, { session: options?.session });
				reject(err);
			});

View on GitHub (pinned to b2c16d5842)

Solutions

  1. Verify the id exists first: db.rocketchat_uploads.findOne({_id: fileId}) (or the store's collection).
  2. Restart the upload (ufsCreate) to obtain a fresh fileId instead of completing a dead one.
  3. Ensure prune/retention jobs are not deleting in-flight uploads; pass the storeName returned by ufsCreate.

Example fix

// before
await Meteor.callAsync('ufsComplete', fileId, 'Uploads');

// after: validate before completing
const file = await Meteor.callAsync('getFileRecord', fileId); // or check collection
if (!file) {
  // restart upload flow: ufsCreate -> upload chunks -> ufsComplete
}
Defensive patterns

Strategy: validation

Validate before calling

const file = await UploadFS.getStore(storeName).getCollection().findOne({ _id: fileId });
if (!file) {
  // restart the upload instead of completing
  return startUpload();
}

Try / catch

try { await ufsComplete(fileId, storeName); } catch (e) { if (isMeteorError(e, 'invalid-file')) { /* re-create upload */ return restartUpload(); } throw e; }

Prevention

When it happens

Trigger: ufsComplete called with a fileId that has no record in the store's collection: fabricated id, record deleted mid-upload, or the file was uploaded to a different store than storeName claims.

Common situations: Client lost the upload session and retried complete with a stale id; uploads collection cleaned by retention/prune jobs between upload and complete; mismatched storeName/fileId pairs in custom clients.

Related errors


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