{"record":{"id":"5254b53c480afd51","repo":"BloopAI/vibe-kanban","slug":"enrollment-code-must-be-6-characters","errorCode":null,"errorMessage":"Enrollment code must be 6 characters.","messagePattern":"Enrollment code must be 6 characters\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/web-core/src/shared/lib/relayPake.ts","lineNumber":45,"sourceCode":"  passwordBytes: Uint8Array;\n  passwordScalar: bigint;\n  xScalar: bigint;\n  clientMessageBytes: Uint8Array;\n}\n\nexport function normalizeEnrollmentCode(rawCode: string): string {\n  return rawCode\n    .trim()\n    .toUpperCase()\n    .replace(/[^A-Z0-9]/g, '');\n}\n\nexport async function startSpake2Enrollment(\n  rawEnrollmentCode: string\n): Promise<{ state: Spake2EnrollmentClientState; clientMessageB64: string }> {\n  const enrollmentCode = normalizeEnrollmentCode(rawEnrollmentCode);\n  if (enrollmentCode.length !== ENROLLMENT_CODE_LENGTH) {\n    throw new Error('Enrollment code must be 6 characters.');\n  }\n\n  const passwordBytes = ENCODER.encode(enrollmentCode);\n  const passwordScalar = await hashToSpake2Scalar(passwordBytes);\n  const xScalar = randomScalar();\n\n  const clientPoint = ed25519.ExtendedPoint.BASE.multiply(xScalar).add(\n    SPAKE2_M.multiply(passwordScalar)\n  );\n  const clientPointBytes = clientPoint.toRawBytes();\n\n  const clientMessage = new Uint8Array(1 + clientPointBytes.length);\n  clientMessage[0] = 0x41; // 'A'\n  clientMessage.set(clientPointBytes, 1);\n\n  return {\n    state: {\n      passwordBytes,","sourceCodeStart":27,"sourceCodeEnd":63,"githubUrl":"https://github.com/BloopAI/vibe-kanban/blob/4deb7eca8f381f7cbc1f9d15515a9ab8f8009053/packages/web-core/src/shared/lib/relayPake.ts#L27-L63","documentation":"startSpake2Enrollment validates that the normalized enrollment code is exactly ENROLLMENT_CODE_LENGTH (6) alphanumeric characters before using it as the SPAKE2 password; otherwise it throws. This is a client-side input guard preventing pointless PAKE handshakes.","triggerScenarios":"Calling startSpake2Enrollment with a code that, after normalizeEnrollmentCode (trim, uppercase, strip non-A-Z0-9), is not 6 chars — e.g. empty input, partially typed code, code containing only invalid characters, or a 7+ character paste.","commonSituations":"User mistypes the 6-character pairing code shown on the host; copying a code with extra whitespace/characters that get stripped leaving fewer than 6; calling the function programmatically with a placeholder like '------' (dashes stripped → 0 chars).","solutions":["Validate/measure normalizeEnrollmentCode(input) client-side before invoking and show a form error.","Prompt the user to re-enter the exact 6-character code from the host display.","Strip surrounding formatting (spaces, hyphens) — normalization already handles it, but length must still be 6 after stripping.","If codes come from an API/QR, confirm the generator emits exactly 6 A-Z0-9 characters."],"exampleFix":"// before\nawait startSpake2Enrollment(codeInput);\n// after\nconst code = normalizeEnrollmentCode(codeInput);\nif (code.length !== 6) {\n  setError('Pairing code must be exactly 6 letters/digits.');\n  return;\n}\nawait startSpake2Enrollment(code);","handlingStrategy":"validation","validationCode":"import { normalizeEnrollmentCode } from '@/shared/lib/relayPake';\nconst code = normalizeEnrollmentCode(userInput);\nif (code.length !== 6) {\n  setError('Enter the 6-character code shown on the host.');\n  return;\n}","typeGuard":"function isValidEnrollmentCode(s: string): boolean {\n  return /^[A-Z0-9]{6}$/.test(s.trim().toUpperCase());\n}","tryCatchPattern":"if (!isValidEnrollmentCode(userInput)) {\n  setError('Pairing code must be exactly 6 letters/digits.');\n  return;\n}\ntry {\n  await startSpake2Enrollment(userInput);\n} catch (e) { showError(e); }","preventionTips":["Use a controlled input with maxLength=6 and alphanumeric filtering","Show live character-count feedback as the user types the code","Always normalize (trim/uppercase/strip symbols) before length checks","If pasted, alert the user when the code length is wrong after normalization"],"tags":["validation","input","pairing","spake2"],"backgroundTag":"input-validation-failed","analyzedSha":"4deb7eca8f381f7cbc1f9d15515a9ab8f8009053","analyzedAt":"2026-08-29T09:24:13.446Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}