thedotmack/claude-mem · error · Error

origin_device_id does not match authenticated X-Device-Id

Error message

origin_device_id does not match authenticated X-Device-Id

What it means

Error "origin_device_id does not match authenticated X-Device-Id" thrown in thedotmack/claude-mem.

Source

Thrown at workers/sync-hub/src/do/SyncHub.ts:382

		} catch (error) {
			console.error("sync-hub fan-out failed (advisory; push unaffected):", error);
		}
	}

	// ---------------------------------------------------------------------
	// Canonical append path and client cursor reads.
	// ---------------------------------------------------------------------

	async pushOps(deviceId: string, ops: PushOp[], deviceName: string | null = null): Promise<PushOutcome> {
		let rows: ValidatedOp[];
		try {
			if (typeof deviceId !== "string" || deviceId.length === 0) throw invalid("deviceId must be non-empty");
			if (!Array.isArray(ops)) throw invalid("ops must be an array");
			rows = await Promise.all(ops.map(async (op, index) => {
				try {
					const parsed = await parseCanonicalOperation(op);
					if (parsed.body.origin_device_id !== deviceId) {
						throw new Error("origin_device_id does not match authenticated X-Device-Id");
					}
					return parsed;
				} catch (error) {
					throw invalid(`ops[${index}] ${error instanceof Error ? error.message : String(error)}`);
				}
			}));
		} catch (error) {
			if (error instanceof Error && error.message.startsWith(INVALID_OPS_PREFIX)) {
				return { refused: true, error: error.message };
			}
			if (isDeviceLimitError(error)) return { refused: true, error: DEVICE_LIMIT_ERROR };
			throw error;
		}

		const sql = this.ctx.storage.sql;
		const now = Date.now();
		const nowDecimal = String(now);
		const headBefore = this.headSeq();

View on GitHub (pinned to d768ba3643)

Solutions

  1. Ensure the client sets origin_device_id in each op body equal to the X-Device-Id header it authenticated with.
  2. If the device id changed (reinstall/rotation), re-register the device and resync rather than replaying ops under the old id.

When it happens

Trigger: Fires in the SyncHub durable object when an operation's origin_device_id does not match the authenticated X-Device-Id header, indicating a spoofed or replayed request, a buggy client sending another device's operations, or a misconfigured proxy stripping headers. Guard at workers/sync-hub/src/do/SyncHub.ts:382 enforces that a device can only write its own operations.

Common situations: See trigger scenarios.

Understand the failure class


AI-assisted analysis of thedotmack/claude-mem@d768ba3643 (2026-08-12). Data as JSON: /api/errors/59415446773364d9. Report an issue: GitHub.