laurent22/joplin · error · Error

Resource file was not created: ${targetPath}

Error message

Resource file was not created: ${targetPath}

What it means

Thrown by the mobile shim.createResourceFromPath after copying the source file to the resource target path: shim.fsDriver().waitTillExists(targetPath) returned false, meaning the file did not appear within the poll window despite copy() not throwing. This guards against silent copy failures on mobile where the FS write is async at the native layer.

Source

Thrown at packages/app-mobile/utils/shim-init-react/shimInitShared.ts:129

		const ext = fileExtension(filePath);
		const mimeType = defaultProps.mime ?? mimeUtils.fromFileExtension(ext) ?? 'image/jpeg';

		let resource = Resource.new();
		resource.id = resourceId;
		resource.mime = mimeType;
		resource.title = basename(filePath);
		resource.file_extension = ext;

		const targetPath = Resource.fullPath(resource);
		await shim.fsDriver().copy(filePath, targetPath);

		if (defaultProps) {
			resource = { ...resource, ...defaultProps };
		}

		const itDoes = await shim.fsDriver().waitTillExists(targetPath);
		if (!itDoes) throw new Error(`Resource file was not created: ${targetPath}`);

		const fileStat = await shim.fsDriver().stat(targetPath);
		resource.size = fileStat.size;

		resource = await Resource.save(resource, { isNew: true });

		return resource;
	};

	shim.detectAndSetLocale = (settings: typeof Setting) => {
		// [
		// 	{
		// 		"countryCode": "US",
		// 		"isRTL": false,
		// 		"languageCode": "fr",
		// 		"languageTag": "fr-US"
		// 	},
		// 	{

View on GitHub (pinned to 2654b33620)

Solutions

  1. Verify the source filePath exists and is readable before calling createResourceFromPath.
  2. Ensure the resource target directory (Resource.fullPath parent) exists and is writable — call shim.fsDriver().mkdir(dirname(targetPath)) if needed.
  3. Check available disk space on the device before resource creation.
  4. If the source is a content:// URI, copy it to a temp file in the app's sandbox first, then pass that temp path.
  5. Increase the waitTillExists timeout if the device storage is consistently slow.

Example fix

// before
const resource = await shim.createResourceFromPath(contentUri);
// after — materialize the content URI into a real file first
const tmp = `${shim.fsDriver().getTempDir()}/${uuid.create()}.jpg`;
await shim.fsDriver().copy(contentUri, tmp);
if (!(await shim.fsDriver().exists(tmp))) throw new Error('Source unreadable');
const resource = await shim.createResourceFromPath(tmp);
Defensive patterns

Strategy: validation

Validate before calling

const fsDriver = shim.fsDriver();
if (!(await fsDriver.exists(filePath))) throw new Error(`Source not found: ${filePath}`);
const targetDir = dirname(Resource.fullPath(Resource.New()));
if (!(await fsDriver.exists(targetDir))) await fsDriver.mkdir(targetDir);
await shim.createResourceFromPath(filePath);

Type guard

function isReadablePath(p) { return typeof p === 'string' && p.length > 0; }

Try / catch

try {
  return await shim.createResourceFromPath(filePath);
} catch (e) {
  if (/Resource file was not created/.test(e.message)) {
    // materialize a content:// URI to a temp file first, then retry
    const tmp = `${shim.fsDriver().getTempDir()}/${uuid.create()}`;
    await shim.fsDriver().copy(filePath, tmp);
    return shim.createResourceFromPath(tmp);
  }
  throw e;
}

Prevention

When it happens

Trigger: shim.fsDriver().copy() silently failed (no throw but no file written); the target directory does not exist or is read-only; storage full so the copy produced nothing; a content:// source URI could not be resolved by the native copy; waitTillExists poll interval/timeout is too short for slow storage.

Common situations: Creating a resource from a camera/gallery URI on Android where the content provider revoked access; target resource dir on external storage that was unmounted; low-disk condition; a React Native FS driver bug returning success without writing.

Related errors


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