laurent22/joplin · error · JoplinError

rejectedByTarget

rejectedByTarget

Error message

error.message

What it means

Re-thrown by the Joplin Server driver when a PUT to .../content fails with HTTP 413 (payload too large) or 409 (conflict). The driver detects these via isRejectedBySyncTargetError and wraps them in a JoplinError with code 'rejectedByTarget', signaling the sync target refused the item so the synchronizer can handle it specially rather than treat it as a generic network error.

Source

Thrown at packages/lib/file-api-driver-joplinServer.ts:204

	}

	private isRejectedBySyncTargetError(error: { code?: number | string; httpCode?: number }) {
		return error.code === 413 || error.code === 409 || error.httpCode === 413 || error.httpCode === 409;
	}

	private isReadyOnlyError(error: { code?: string }) {
		return error && error.code === 'isReadOnly';
	}

	public async put(path: string, content: string | Buffer | null, options: ExecOptions & { shareId?: string } = null) {
		try {
			const output = await this.api().exec('PUT', `${this.apiFilePath_(path)}/content`, options && options.shareId ? { share_id: options.shareId } : null, content, {
				'Content-Type': 'application/octet-stream',
			}, options);
			return output;
		} catch (error) {
			if (this.isRejectedBySyncTargetError(error)) {
				throw new JoplinError(error.message, 'rejectedByTarget');
			}

			if (this.isReadyOnlyError(error)) {
				throw new JoplinError(error.message, 'isReadOnly');
			}

			throw error;
		}
	}

	public async multiPut(items: MultiPutItem[], options: ExecOptions = null) {
		const output = await this.api().exec('PUT', 'api/batch_items', null, { items: items }, null, options);

		for (const [, response] of Object.entries<{ error?: { code?: string | number; httpCode?: number } }>(output.items)) {
			if (response.error && this.isRejectedBySyncTargetError(response.error)) {
				response.error.code = 'rejectedByTarget';
			} else if (response.error && this.isReadyOnlyError(response.error as { code?: string })) {
				response.error.code = 'isReadOnly';

View on GitHub (pinned to 2654b33620)

Solutions

  1. Check the underlying HTTP code (413 vs 409) in the wrapped error.message — 413 means reduce payload size or raise the server's upload limit; 409 means resolve the sync conflict and re-sync.
  2. For 413: increase Joplin Server max body size / resource size cap, or split/truncate the resource.
  3. For 409: let the normal sync conflict resolution run, or force-sync the item after confirming no other client is mid-edit.
  4. Ensure the Joplin Server and client versions are compatible.

Example fix

// before
await fileApi.put(path, content, { shareId });
// after - branch on the re-thrown code
try { await fileApi.put(path, content, { shareId }); }
catch (e) {
  if (e.code === 'rejectedByTarget') {
    if (/413|too large|payload/i.test(e.message)) throw new Error('Resource exceeds server limit');
    // 409 conflict - defer to conflict resolution
  }
  throw e;
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-check size if known to avoid a 413 round-trip.
if (content && typeof content === 'string' && content.length > MAX_PUT_BYTES) {
  throw new Error('Payload too large for Joplin Server');
}

Type guard

function isRejectedByTarget(e: any): e is { code: 'rejectedByTarget'; message: string } {
  return e && e.code === 'rejectedByTarget';
}

Try / catch

try {
  await fileApi.put(path, content, { shareId });
} catch (e) {
  if (isRejectedByTarget(e)) {
    if (/413|too large/i.test(e.message)) { /* shrink resource or raise server limit */ }
    else { /* 409 conflict - defer to sync conflict resolution */ }
  } else throw e;
}

Prevention

When it happens

Trigger: Uploading note/resource content to Joplin Server where the body exceeds the server's max payload (413), or a concurrent sync/lock conflict produced a 409. The PUT is the per-item content upload inside put().

Common situations: Attaching a very large resource (image, PDF) exceeding the server upload limit; two clients editing and syncing the same item simultaneously; server-side quota reached; older server version with stricter limits.

Related errors


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