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
- Verify the local resource file still exists at the expected path in the Joplin resources directory.
- If the resource was intentionally deleted, remove its metadata so sync doesn't try to upload it, or let sync reconcile the deletion.
- Restore the missing file from backup if the resource should still exist.
- 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
- Verify local resource files exist before attempting file-source uploads.
- Avoid manual cleanup of the resources directory while sync is running.
- Handle missing-file errors by reconciling resource metadata rather than failing the sync.
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
- fileNotFound
- Please specify the sync target path.
- uploadBlob: ${method} ${url}: ${error.toString()}
- AWS S3 bucket not found: ${SyncTargetAmazonS3.s3BucketName()
- downloadLimiter
AI-assisted analysis of laurent22/joplin@2654b33620 (2026-08-12).
Data as JSON: /api/errors/4b5bec99454e9c72.
Report an issue: GitHub.