{"record":{"id":"2d9c9349e2790c15","repo":"koala73/worldmonitor","slug":"invalid-field-touppercase","errorCode":null,"errorMessage":"INVALID_${field.toUpperCase()}","messagePattern":"INVALID_(.+?)","errorType":"validation","errorClass":"ConvexError","httpStatus":null,"severity":"error","filePath":"convex/companyMonitoring/_shared.ts","lineNumber":24,"sourceCode":"  type NormalizedMonitoredCompanyInput,\n} from \"../../shared/company-monitoring-contract\";\n\nexport const COMPANY_LIMIT = COMPANY_MONITORING_LIMITS.maxCompaniesPerAccount;\nexport const COMPANY_MONITORING_CLAIM_POLICY_VERSION = 1;\nconst CROCKFORD = \"0123456789ABCDEFGHJKMNPQRSTVWXYZ\";\nconst REQUEST_CONTROL = /[\\u0000-\\u001f\\u007f-\\u009f\\u00ad\\u061c\\u180e\\u200b-\\u200f\\u2028-\\u202e\\u2060-\\u206f\\ufeff\\ufff9-\\ufffb]/u;\n\ntype CompanyMonitoringCtx = MutationCtx | QueryCtx;\n\nexport function hasCurrentCompanyMonitoringClaimPolicy(\n  account: Pick<Doc<\"companyMonitoringAccounts\">, \"claimPolicyVersion\">,\n): boolean {\n  return (account.claimPolicyVersion ?? 0) >= COMPANY_MONITORING_CLAIM_POLICY_VERSION;\n}\n\nexport function normalizeRequestId(value: string, field = \"clientRequestId\"): string {\n  if (typeof value !== \"string\" || REQUEST_CONTROL.test(value)) {\n    throw new ConvexError(`INVALID_${field.toUpperCase()}`);\n  }\n  const normalized = value.normalize(\"NFC\").trim();\n  if (!normalized || new TextEncoder().encode(normalized).byteLength > 64) {\n    throw new ConvexError(`INVALID_${field.toUpperCase()}`);\n  }\n  return normalized;\n}\n\nexport async function fingerprint(value: unknown): Promise<string> {\n  const bytes = new TextEncoder().encode(JSON.stringify(value));\n  const digest = await crypto.subtle.digest(\"SHA-256\", bytes);\n  return Array.from(new Uint8Array(digest), (byte) => byte.toString(16).padStart(2, \"0\")).join(\"\");\n}\n\nexport function randomFence(): string {\n  const bytes = new Uint8Array(32);\n  crypto.getRandomValues(bytes);\n  return Array.from(bytes, (byte) => byte.toString(16).padStart(2, \"0\")).join(\"\");","sourceCodeStart":6,"sourceCodeEnd":42,"githubUrl":"https://github.com/koala73/worldmonitor/blob/eeab0a219fce0f02a00603b532dbae9041b934ac/convex/companyMonitoring/_shared.ts#L6-L42","documentation":"Dynamic validation sentinel from normalizeRequestId in the Company Monitoring shared helpers: a request-identifier field (the embedded INVALID_<FIELD> names it, e.g. INVALID_REQUESTID) failed validation — empty after trim, over length, or containing control/invisible Unicode characters matched by REQUEST_CONTROL. The input at fault is the request-correlation identifier supplied by the client.","triggerScenarios":"Thrown at convex/companyMonitoring/_shared.ts:24 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Regenerate the request id client-side: a fresh UUID or Crockford-style id with no control or invisible characters","Validate the id (non-empty, within length, no control chars) before submitting","If the client builds ids from user text, sanitize or reject that copy source"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"eeab0a219fce0f02a00603b532dbae9041b934ac","analyzedAt":"2026-08-21T16:51:25.751Z","contentChangedAt":"2026-08-21T16:51:25.751Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}