koala73/worldmonitor · error · ConvexError

INVALID_COMPANY_MONITORING_WORKER_ID

Error message

INVALID_COMPANY_MONITORING_WORKER_ID

What it means

Thrown by normalizeWorkerId in orchestration.ts when the supplied workerId does not match the regex /^[A-Za-z0-9._:-]{1,64}$/. Worker ids are used as lease owners and audit identifiers, so they must be short, printable, and deterministic; malformed ids are rejected before any work is claimed.

Source

Thrown at convex/companyMonitoring/orchestration.ts:188

function scanWindowAt(timestamp: number) {
  const windowEnd = Math.floor(timestamp / WINDOW_BUCKET_MS) * WINDOW_BUCKET_MS;
  return { windowStart: windowEnd - WINDOW_MS, windowEnd };
}

async function scanWorkKey(args: {
  ownerAccountId: string;
  cohortKey: string;
  source: Source;
  windowStart: number;
  windowEnd: number;
  queryVersion: string;
}) {
  return fingerprint({ version: "cm-work-v1", ...args });
}

function normalizeWorkerId(workerId: string): string {
  if (!WORKER_ID.test(workerId)) {
    throw new ConvexError("INVALID_COMPANY_MONITORING_WORKER_ID");
  }
  return workerId;
}

async function timingSafeEqualStrings(left: string, right: string): Promise<boolean> {
  const encoder = new TextEncoder();
  const [leftDigest, rightDigest] = await Promise.all([
    crypto.subtle.digest("SHA-256", encoder.encode(left)),
    crypto.subtle.digest("SHA-256", encoder.encode(right)),
  ]);
  const leftBytes = new Uint8Array(leftDigest);
  const rightBytes = new Uint8Array(rightDigest);
  let mismatch = 0;
  for (let index = 0; index < leftBytes.length; index += 1) {
    mismatch |= leftBytes[index]! ^ rightBytes[index]!;
  }
  return mismatch === 0;
}

View on GitHub (pinned to ffec79ac33)

Solutions

  1. Configure the worker with a stable id matching the allowed character set and length.
  2. Validate workerId against the regex client-side before the first call.
  3. Generate ids from a known-safe alphabet (e.g., base32/base64url trimmed to 64).

Example fix

// before
const workerId = `${hostname}:${process.ppid}:${Date.now()}`; // may exceed 64 or use bad chars

// after
const workerId = sanitizeWorkerId(`${hostname}-${process.ppid}`);
if (!/^[A-Za-z0-9._:-]{1,64}$/.test(workerId)) throw new Error("bad worker id");
Defensive patterns

Strategy: validation

Validate before calling

const WORKER_ID = /^[A-Za-z0-9._:-]{1,64}$/;
if (!WORKER_ID.test(workerId)) throw new Error("invalid worker id");

Type guard

function isValidWorkerId(id: string): boolean {
  return /^[A-Za-z0-9._:-]{1,64}$/.test(id);
}

Prevention

When it happens

Trigger: Calling a worker-facing mutation (e.g., claimNextWork) with a workerId containing characters outside [A-Za-z0-9._:-] or longer than 64 characters.

Common situations: Worker not setting its id; embedding a UUID with disallowed characters; appending a timestamp/hostname that exceeds 64 chars; passing an empty string.

Related errors


AI-assisted analysis of koala73/worldmonitor@ffec79ac33 (2026-08-12). Data as JSON: /api/errors/c8882909ae78ce1b. Report an issue: GitHub.