thedotmack/claude-mem · error · Error

device_id must be 1-128 characters

Error message

device_id must be 1-128 characters

What it means

Validation guard in SyncHubDO.renameDevice: the trimmed deviceId must be 1-128 characters to match the device-id constraints enforced at registration. renameDevice updates the display name in the devices table and returns whether a row matched.

Solutions

  1. Trim the id and check length is between 1 and 128 before calling renameDevice
  2. Reuse the exact device id issued at registration rather than a derived value
  3. Check the return value: false means no device with that id exists, not a rename failure

Example fix

// before
await stub.renameDevice(rawId, name);
// after
const id = rawId.trim();
if (id.length === 0 || id.length > 128) throw new Error('invalid device id');
await stub.renameDevice(id, name);
Defensive patterns

Strategy: validation

Validate before calling

const id = rawId.trim();
if (id.length < 1 || id.length > 128) throw new Error('device id must be 1-128 chars');
const nm = normalizeDeviceName(name);
if (nm === null) throw new Error('device name must be 1-80 chars');

Type guard

const isRenamableDeviceId = (id: unknown): id is string => typeof id === 'string' && id.trim().length >= 1 && id.trim().length <= 128;

Try / catch

try {
  return await stub.renameDevice(deviceId, name);
} catch (e) {
  if (String(e).includes('device_id must be 1-128 characters')) return false;
  throw e;
}

Prevention

When it happens

Trigger: Renaming with an empty id after trimming, or an id longer than 128 chars (e.g. a full URL or concatenated token passed as the id).

Common situations: Client storing a prefixed/over-long identifier, UI sending an untrimmed whitespace-only id, schema change where device ids became longer after migration.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of thedotmack/claude-mem@d8bc9755e7 (2026-09-17). Data as JSON: /api/errors/bb3fc7a4e3a32d23. Report an issue: GitHub.

Appendix: source

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

				connection_state: connected.has(row.device_id) ? "connected" as const : "disconnected" as const,
			};
		});
		return {
			protocol_version: 1,
			user_id: userId,
			epoch: this.meta("epoch"),
			head_seq: head,
			projected_seq: projected,
			projection_lag_ops: decimalLag(head, projected),
			sync_health: head === projected ? "healthy" : "projector_lagging",
			devices,
		};
	}

	renameDevice(deviceId: string, name: string): boolean {
		const normalizedId = deviceId.trim();
		const normalizedName = normalizeDeviceName(name);
		if (normalizedId.length === 0 || normalizedId.length > 128) throw invalid("device_id must be 1-128 characters");
		if (normalizedName === null) throw invalid("name must be 1-80 characters");
		return this.ctx.storage.sql.exec(
			"UPDATE devices SET name = ? WHERE device_id = ?",
			normalizedName,
			normalizedId,
		).rowsWritten > 0;
	}

	// ---------------------------------------------------------------------
	// Authoritative projection checkpoint and short per-user lease.
	// ---------------------------------------------------------------------

	acquireProjectionLease(targetSeq: string, now = Date.now()): ProjectionLease {
		const target = assertCanonicalDecimal(targetSeq);
		const head = this.headSeq();
		if (compareCanonicalDecimals(target, head) > 0) throw projectionError("target_seq exceeds head_seq");
		const projected = this.projectedSeq();
		const existingToken = this.metaOptional("projection_lease_token");

View on GitHub (pinned to d8bc9755e7)