laurent22/joplin · error · Error

s3UploadFileFrom: file does not exist

Error message

s3UploadFileFrom: file does not exist

What it means

Thrown by FileApiDriverAmazonS3.s3UploadFileFrom() when shim.fsDriver().exists(path) returns false before attempting to read and upload the local file. The function is used when options.source === 'file' on a put() call — the sync engine is trying to upload a resource file (e.g. an attachment body) whose local path no longer exists.

Source

Thrown at packages/lib/file-api-driver-amazon-s3.js:102

			});
		});
	}

	async s3PutObject(key, body) {
		return new Promise((resolve, reject) => {
			this.api().send(new PutObjectCommand({
				Bucket: this.s3_bucket_,
				Key: key,
				Body: body,
			}), (error, response) => {
				if (error) reject(error);
				else resolve(response);
			});
		});
	}

	async s3UploadFileFrom(path, key) {
		if (!shim.fsDriver().exists(path)) throw new Error('s3UploadFileFrom: file does not exist');
		const body = await shim.fsDriver().readFile(path, 'base64');
		const fileStat = await shim.fsDriver().stat(path);
		return new Promise((resolve, reject) => {
			this.api().send(new PutObjectCommand({
				Bucket: this.s3_bucket_,
				Key: key,
				Body: Buffer.from(body, 'base64'),
				ContentLength: `${fileStat.size}`,
			}), (error, response) => {
				if (error) reject(error);
				else resolve(response);
			});
		});
	}

	async s3DeleteObject(key) {
		return new Promise((resolve, reject) => {
			this.api().send(new DeleteObjectCommand({

View on GitHub (pinned to 2654b33620)

Solutions

  1. Verify the local resource file still exists at the expected path in the Joplin resources directory.
  2. If the resource was intentionally deleted, remove its metadata so sync doesn't try to upload it, or let sync reconcile the deletion.
  3. Restore the missing file from backup if the resource should still exist.
  4. Check for disk/storage issues (unmounted external storage, full disk) that prevented the file from being written.
Defensive patterns

Strategy: validation

Validate before calling

import shim from './shim';
// Before requesting an upload from a file
if (!await shim.fsDriver().exists(localPath)) {
  // the resource blob is gone; skip or reconcile the resource metadata
  logger.warn('Resource file missing, skipping upload', localPath);
  return;
}

Try / catch

try {
  await driver.put(path, null, { source: 'file', path: localPath });
} catch (error) {
  if (/file does not exist/.test(error.message)) {
    // reconcile: mark resource as deleted or restore from backup
    return;
  }
  throw error;
}

Prevention

When it happens

Trigger: The sync engine calls driver.put(path, null, { source: 'file', path: localPath }) to upload a resource, but the local file at localPath has been deleted, moved, or was never written to disk. s3UploadFileFrom checks existence and throws immediately.

Common situations: A resource's blob file was deleted from the resource directory (manual cleanup, disk cleanup tool); the file is on external/removable storage that was unmounted; a previous operation failed to write the blob; race between resource deletion and sync.

Related errors


AI-assisted analysis of laurent22/joplin@2654b33620 (2026-08-12). Data as JSON: /api/errors/4b5bec99454e9c72. Report an issue: GitHub.