laurent22/joplin · error · Error

Delta link missing: ${JSON.stringify(response)}

Error message

Delta link missing: ${JSON.stringify(response)}

What it means

Thrown by the OneDrive driver's delta pagination logic. When the delta response has no @odata.nextLink (more pages coming) it expects an @odata.deltaLink (feed complete, use this token next time). If neither is present the response shape is unexpected and the driver refuses to continue, since proceeding would lose the delta cursor.

Source

Thrown at packages/lib/file-api-driver-onedrive.ts:356

		// At OneDrive for Business delta requests can only make at the root of OneDrive.  Not sure but it's possible that
		// the delta API also returns events for files that are copied outside of the app directory and later deleted or
		// modified when using OneDrive Personal).

		for (let i = 0; i < response.value.length; i++) {
			const v = response.value[i];
			if (v.parentReference.id !== pathId) continue;
			items.push(this.makeItem_(v));
		}

		output.items = output.items.concat(items);

		let nextLink = null;

		if (response['@odata.nextLink']) {
			nextLink = response['@odata.nextLink'];
			output.hasMore = true;
		} else {
			if (!response['@odata.deltaLink']) throw new Error(`Delta link missing: ${JSON.stringify(response)}`);
			nextLink = response['@odata.deltaLink'];
		}

		output.context = { nextLink: nextLink };

		// https://dev.onedrive.com/items/view_delta.htm
		// The same item may appear more than once in a delta feed, for various reasons. You should use the last occurrence you see.
		// So remove any duplicate item from the array.
		const temp: ItemStat[] = [];
		const seenPaths = [];
		for (let i = output.items.length - 1; i >= 0; i--) {
			const item = output.items[i];
			if (seenPaths.indexOf(item.path) >= 0) continue;
			temp.splice(0, 0, item);
			seenPaths.push(item.path);
		}

		output.items = temp;

View on GitHub (pinned to 2654b33620)

Solutions

  1. Re-authenticate the OneDrive account (re-link the sync target) — expired tokens often produce malformed responses.
  2. Inspect the JSON in the message to see what OneDrive actually returned (error body, throttling JSON, etc.).
  3. Retry after a short delay — transient Graph API anomalies frequently self-correct.
  4. Confirm the app requests the Files.ReadWrite.All scope and the endpoint URL is the standard Graph delta URL.

Example fix

// before
if (!response['@odata.deltaLink']) throw new Error(`Delta link missing: ${JSON.stringify(response)}`);
// after - tolerate throttling/error envelopes and retry
if (!response['@odata.deltaLink'] && !response.error) {
  throw new Error(`Delta link missing: ${JSON.stringify(response)}`);
}
if (response.error) { /* re-auth or back off and retry */ }
Defensive patterns

Strategy: retry

Validate before calling

// Re-check token validity and endpoint shape before delta.
if (!tokenValid()) await reauthenticate();
const probe = await fetch(deltaUrl, { headers });
if (!probe.ok || probe.headers.get('content-type')?.includes('text/html')) {
  throw new Error('OneDrive delta endpoint returned a non-JSON response; check auth/URL.');
}

Type guard

function hasDeltaOrNextLink(response: any): boolean {
  return !!response && (!!response['@odata.deltaLink'] || !!response['@odata.nextLink']);
}

Try / catch

for (const delay of [0, 1000, 5000]) {
  await sleep(delay);
  try {
    const response = await graphDelta();
    if (hasDeltaOrNextLink(response)) { /* proceed */ break; }
    if (response?.error) throw new Error('OneDrive error: ' + JSON.stringify(response.error));
  } catch (e) { if (delay === 5000) throw e; }
}

Prevention

When it happens

Trigger: Calling delta() on OneDrive where the Graph API response omits both @odata.nextLink and @odata.deltaLink — e.g. malformed/empty response, API version returning a different shape, token expiry causing a truncated response.

Common situations: OneDrive Graph API version drift; expired/de auth token producing a non-delta body; throttling response (Retry-After) mis-parsed as a delta; corporate SharePoint endpoint with non-standard behavior; rare backend hiccup returning an empty envelope.

Related errors


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