thedotmack/claude-mem · error · Error
invalid_ops: device name must be at most 80 characters
Error message
invalid_ops: device name must be at most 80 characters
What it means
invalid("device name must be at most 80 characters") is thrown by the module-level normalizeDeviceName when a provided device name trims to more than 80 characters. Null or whitespace-only names are normalized to null (no name), but any real name exceeding the cap is rejected rather than truncated.
Solutions
- Truncate or shorten the device name to <= 80 characters before calling the API.
- Use a short human label (e.g. "MacBook Pro") instead of the raw user-agent string.
- Fall back to null (omit the name) when no concise label is available.
- Trim first, then slice: value.trim().slice(0, 80) if truncation is acceptable.
Example fix
// before registerDevice(deviceId, navigator.userAgent); // usually > 80 chars // after const name = shortDeviceLabel() ?? null; // e.g. "Chrome on macOS" registerDevice(deviceId, name && name.slice(0, 80));
Defensive patterns
Strategy: validation
Validate before calling
function assertValidDeviceName(name: string | null): string | null {
if (name === null) return null;
const n = name.trim();
if (n.length === 0) return null;
if (n.length > 80) throw new RangeError(`device name must be at most 80 characters, got ${n.length}`);
return n;
} Type guard
function isValidDeviceName(v: unknown): v is string | null {
return v === null || (typeof v === "string" && v.trim().length <= 80);
} Prevention
- Never use navigator.userAgent as a device name; use a short friendly label.
- Trim and cap names client-side: name.trim().slice(0, 80).
- Send null instead of an empty or oversized name when no good label exists.
- Add a maxLength=80 attribute to device-name form inputs.
When it happens
Trigger: Registering or renaming a device with a display name longer than 80 characters after trimming; passing a user-entered label like a long browser user-agent string as the device name.
Common situations: Clients auto-filling device names from navigator.userAgent (often > 80 chars); iOS/Android device marketing names with model suffixes; copy-pasted long labels; failing to truncate before sending from a thin client.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- invalid_ops: deviceId must be 1-128 characters
- device_id must be 1-128 characters
- Adapter rejected input
- agent_event source_id must belong to project_id and team_id
- canonical content
AI-assisted analysis of thedotmack/claude-mem@d8bc9755e7 (2026-09-17).
Data as JSON: /api/errors/6cd0e79c05fce928.
Report an issue: GitHub.
Appendix: source
Thrown at workers/sync-hub/src/do/SyncHub.ts:889
private setMeta(key: string, value: string): void {
this.ctx.storage.sql.exec(
"INSERT INTO meta (k, v) VALUES (?, ?) ON CONFLICT(k) DO UPDATE SET v=excluded.v",
key,
value,
);
}
private deleteMeta(key: string): void {
this.ctx.storage.sql.exec("DELETE FROM meta WHERE k = ?", key);
}
}
function normalizeDeviceName(value: string | null): string | null {
if (value === null) return null;
const normalized = value.trim();
if (normalized.length === 0) return null;
if (normalized.length > 80) throw invalid("device name must be at most 80 characters");
return normalized;
}
function decimalLag(head: string, cursor: string): string {
const canonicalHead = assertCanonicalDecimal(head);
const canonicalCursor = assertCanonicalDecimal(cursor);
if (compareCanonicalDecimals(canonicalCursor, canonicalHead) >= 0) return "0";
return (BigInt(canonicalHead) - BigInt(canonicalCursor)).toString(10);
}
View on GitHub (pinned to d8bc9755e7)