koala73/worldmonitor · warning · ConvexError
COMPANY_MONITORING_${field}_INVALID
Error message
COMPANY_MONITORING_${field}_INVALID What it means
Thrown by admissionIdentifier (admission.ts:25-29) when a workerId, leaseToken, or classificationRunId does not match the ADMISSION_ID regex /^[A-Za-z0-9._:-]{1,128}$/. The ConvexError message is COMPANY_MONITORING_<FIELD>_INVALID, where field is one of ADMISSION_WORKER_ID, ADMISSION_LEASE, or CLASSIFICATION_RUN_ID. This validates admission-pipeline identifiers before they are persisted, ensuring they are compact, printable, and bounded.
Source
Thrown at convex/companyMonitoring/admission.ts:27
COMPANY_MONITORING_DEFAULT_CONFIDENCE_FLOORS,
COMPANY_MONITORING_RETRY_POLICY,
COMPANY_MONITORING_SOURCE_POLICY_VERSION,
evaluateCompanyMonitoringClassifierTransportFailure,
evaluateCompanyMonitoringClassification,
} from "../../scripts/lib/company-monitoring-classification.mjs";
import { fingerprint, randomFence } from "./_shared";
import {
companyMonitoringCandidateEvidenceSnapshotDigest as candidateEvidenceSnapshotDigest,
companyMonitoringEvidenceShape as evidenceShape,
} from "./admissionSnapshot";
const ADMISSION_LEASE_MS = 5 * 60 * 1000;
const ADMISSION_ID = /^[A-Za-z0-9._:-]{1,128}$/;
const ADMISSION_MODEL_VERSION = /^[^\u0000-\u001f\u007f]{1,200}$/u;
function admissionIdentifier(value: string, field: string) {
if (!ADMISSION_ID.test(value)) {
throw new ConvexError(`COMPANY_MONITORING_${field}_INVALID`);
}
return value;
}
function admissionModelVersion(value: string) {
if (
value !== value.trim() ||
!ADMISSION_MODEL_VERSION.test(value)
) {
throw new ConvexError("COMPANY_MONITORING_MODEL_VERSION_INVALID");
}
return value;
}
function canonicalValue(value: unknown): unknown {
if (Array.isArray(value)) return value.map(canonicalValue);
if (value && typeof value === "object") {
const row = value as Record<string, unknown>;View on GitHub (pinned to ffec79ac33)
Solutions
- Generate worker/lease/run ids from the allowed alphabet only: A-Z, a-z, 0-9, and the separators . _ : -. Prefer ULID, a hex hash, or a slugified id.
- Ensure the id is between 1 and 128 characters — truncate generated ids (like the system-<decision>-<candidateId> pattern at admission.ts:138) before passing, not after.
- Strip or reject disallowed characters at the worker before invoking the admission mutation.
Example fix
// before — worker passes a raw hostname with invalid chars const workerId = os.hostname(); // e.g. 'worker_prod us-1' // after — slug to allowed alphabet const workerId = (os.hostname() || 'worker').replace(/[^A-Za-z0-9._:-]/g, '-').slice(0, 128);
Defensive patterns
Strategy: validation
Validate before calling
const ADMISSION_ID = /^[A-Za-z0-9._:-]{1,128}$/;
function isValidAdmissionId(value: unknown): value is string {
return typeof value === "string" && ADMISSION_ID.test(value);
}
// before calling an admission mutation:
if (!isValidAdmissionId(workerId)) workerId = slugify(workerId).slice(0, 128) || crypto.randomUUID(); Type guard
function isValidAdmissionId(value: unknown): value is string {
const ADMISSION_ID = /^[A-Za-z0-9._:-]{1,128}$/;
return typeof value === "string" && ADMISSION_ID.test(value);
} Prevention
- Generate workerId, leaseToken, and classificationRunId from the allowed alphabet (A-Za-z0-9._:-) only.
- Truncate generated ids to 128 chars before passing, not after the mutation rejects them.
- Slugify any hostname-derived worker id to strip invalid characters (spaces, slashes, unicode).
When it happens
Trigger: An admission mutation (leaseAdmissionCandidate, resolveAdmissionCandidate, etc.) is called with a workerId/leaseToken/classificationRunId containing spaces, slashes, unicode, or exceeding 128 characters. A system-generated classificationRunId (e.g. 'system-reject-...') is sliced to 128 chars but still contains an invalid character. A worker passes a UUID with hyphens in unexpected positions or a free-form string.
Common situations: A worker process generates ids with characters outside the allowed alphabet (e.g. base64 with '+'/'='/'/'). A classificationRunId built from a candidate id + suffix exceeds 128 chars before slicing. A test passes a descriptive string with spaces. A worker id includes unicode from a misconfigured hostname.
Related errors
- INVALID_${field.toUpperCase()}
- INVALID_COMPANY_PATCH
- COMPANY_MONITORING_EVIDENCE_SUBJECTS_INVALID
- COMPANY_MONITORING_EVIDENCE_BATCH_INVALID
- COMPANY_MONITORING_EVIDENCE_EXPANSION_INVALID
AI-assisted analysis of koala73/worldmonitor@ffec79ac33 (2026-08-12).
Data as JSON: /api/errors/d839a7dbb5727dbf.
Report an issue: GitHub.