{"record":{"id":"cdb7bfba09c2dbc0","repo":"schollz/croc","slug":"custom-codes-must-use-printable-ascii-characters","errorCode":null,"errorMessage":"Custom codes must use printable ASCII characters","messagePattern":"Custom codes must use printable ASCII characters","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"web/src/protocol/client.ts","lineNumber":65,"sourceCode":"  return new DOMException(\"Transfer cancelled\", \"AbortError\");\n}\n\nfunction checkAbort(signal?: AbortSignal) {\n  if (signal?.aborted) throw abortError();\n}\n\nfunction requirePakeVersion(version: number | undefined) {\n  if (version !== PAKE_PROTOCOL_VERSION) {\n    throw new Error(\n      `Peer uses unsupported PAKE protocol version ${version ?? 0}; upgrade both croc clients`,\n    );\n  }\n}\n\nfunction validateSecret(secret: string) {\n  if (secret.length < 6) throw new Error(\"Code must be at least 6 characters\");\n  if (!/^[\\x20-\\x7e]+$/.test(secret)) {\n    throw new Error(\"Custom codes must use printable ASCII characters\");\n  }\n}\n\nfunction controlPort(relayAddress: string) {\n  try {\n    const parsed = new URL(\n      relayAddress.includes(\"://\") ? relayAddress : `tcp://${relayAddress}`,\n    );\n    return parsed.port || CONTROL_PORT;\n  } catch {\n    return CONTROL_PORT;\n  }\n}\n\nfunction dataPorts(banner: string) {\n  const ports = banner\n    .split(\",\")\n    .map((port) => port.trim())","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/schollz/croc/blob/e25f1bdc04f07f094d50b0a1bf67e2563944b57a/web/src/protocol/client.ts#L47-L83","documentation":"validateSecret requires the whole code to match /^[\\x20-\\x7e]+$/ (printable ASCII, space through tilde). Any non-ASCII letter, emoji, tab, or control character makes the test fail before the transfer starts. This mirrors croc's CLI restriction so the code maps cleanly onto the wire protocol.","triggerScenarios":"A code containing accented characters (e.g. 'café-code'), CJK text, emoji, or an embedded tab/newline pasted from a chat message; IME autocorrect altering an ASCII code.","commonSituations":"Copy-paste from messengers that insert zero-width characters or smart quotes; non-English keyboard layouts producing accents; trailing newline included in a pasted value.","solutions":["Strip or retype non-ASCII characters; use only printable ASCII in the code","Normalize pasted input before validation: trim whitespace and remove zero-width characters","Enforce the same pattern in the UI input field so the user gets immediate feedback"],"exampleFix":"// before\nconst secret = pastedText; // contains a zero-width space or accent\nawait sendFiles({ files, secret, settings });\n\n// after\nconst secret = pastedText.replace(/[^\\x20-\\x7e]/g, \"\").trim();\nif (secret.length >= 6) await sendFiles({ files, secret, settings });","handlingStrategy":"validation","validationCode":"const PRINTABLE_ASCII = /^[\\x20-\\x7e]+$/;\nfunction normalizeSecret(s) {\n  return s.replace(/[^\\x20-\\x7e]/g, \"\").trim();\n}\nconst secret = normalizeSecret(raw);\nif (!PRINTABLE_ASCII.test(secret)) throw new Error(\"Code must be printable ASCII\");","typeGuard":null,"tryCatchPattern":"try { await sendFiles(opts); } catch (e) {\n  if (/printable ASCII/.test(e.message)) { setCodeError(\"Use plain letters, numbers and symbols only\"); return; }\n  throw e;\n}","preventionTips":["Sanitize pasted codes (strip zero-width chars, smart quotes, newlines) before storing","Show a live pattern indicator on the code input","Beware IME autocorrect when users type codes on mobile"],"tags":["validation","user-input","ascii","passphrase"],"backgroundTag":null,"analyzedSha":"e25f1bdc04f07f094d50b0a1bf67e2563944b57a","analyzedAt":"2026-08-15T12:53:39.096Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}