{"record":{"id":"18d5da6f9ab61df4","repo":"schollz/croc","slug":"text-transfers-are-not-supported-yet","errorCode":null,"errorMessage":"Text transfers are not supported yet","messagePattern":"Text transfers are not supported yet","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"web/src/protocol/metadata.ts","lineNumber":64,"sourceCode":"}\n\nexport function normalizeOutgoingFileName(value: string) {\n  // Go's unicode.IsPrint accepts ASCII space but rejects the other Unicode\n  // separator characters commonly inserted into filenames by macOS.\n  const compatible = value.replace(/\\p{Z}+/gu, \" \");\n  return normalizeFilePath(\".\", compatible).name;\n}\n\nfunction finiteSize(file: WireFileInfo) {\n  const size = file.s ?? 0;\n  if (!Number.isSafeInteger(size) || size < 0) {\n    throw new Error(`Invalid file size for ${file.n ?? \"unnamed file\"}`);\n  }\n  return size;\n}\n\nexport function validateSenderInfo(info: SenderInfoWire): TransferOffer {\n  if (info.SendingText) throw new Error(\"Text transfers are not supported yet\");\n  if (info.HashAlgorithm && info.HashAlgorithm !== \"xxhash\") {\n    throw new Error(`Hash algorithm \"${info.HashAlgorithm}\" is not supported`);\n  }\n\n  const destinations = new Set<string>();\n  const files: OfferedFile[] = [];\n  let totalSize = 0;\n  for (const wire of info.FilesToTransfer ?? []) {\n    if (wire.sy) throw new Error(\"Symlink transfers are not supported in the browser\");\n    const normalized = normalizeFilePath(wire.fr ?? \".\", wire.n ?? \"\");\n    if (destinations.has(normalized.path)) {\n      throw new Error(`Duplicate destination path: ${normalized.path}`);\n    }\n    destinations.add(normalized.path);\n    const size = finiteSize(wire);\n    totalSize += size;\n    if (!Number.isSafeInteger(totalSize)) throw new Error(\"Transfer size is too large\");\n    files.push({","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/schollz/croc/blob/e25f1bdc04f07f094d50b0a1bf67e2563944b57a/web/src/protocol/metadata.ts#L46-L82","documentation":"validateSenderInfo() rejects any offer with a truthy SendingText field. The browser client implements file transfer only; croc's text-message mode ('croc send --text') has no receiving UI/sink here, so such offers are refused upfront rather than half-processed.","triggerScenarios":"A peer runs 'croc send --text \"...\"' and the receiver is this browser client; validateSenderInfo sees info.SendingText truthy and throws before inspecting files.","commonSituations":"Sender accidentally in text mode (clipboard paste auto-detection in croc CLI); mixed senders where one user tries to send a quick note alongside a transfer; CI tests exercising text mode against the web receiver.","solutions":["On the sender, re-send as a file: write the text to a file or use croc's file mode so SendingText is unset.","As the web receiver, surface a clear 'text transfers are unsupported' message and ask the peer to resend as a file.","If building a client on top, check SendingText before accepting and guide the user to file mode."],"exampleFix":"# before (sender)\ncroc send --text \"hello\"\n# after (sender)\necho \"hello\" > note.txt && croroc send note.txt","handlingStrategy":"try-catch","validationCode":"function isFileOnlyOffer(info: SenderInfoWire): boolean {\n  return !info.SendingText;\n}\nif (!isFileOnlyOffer(info)) {\n  notifyUser(\"ask sender to resend as a file — text mode is unsupported\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  const offer = validateSenderInfo(info);\n} catch (error) {\n  if (error instanceof Error && error.message === \"Text transfers are not supported yet\") {\n    showNotice(\"The peer sent a text message; ask them to send it as a file.\");\n    return;\n  }\n  throw error;\n}","preventionTips":["Use croc's file mode when the receiver is the web client; avoid --text.","Feature-check SendingText before accepting and prompt the peer to re-send.","Track client capability negotiation if you build a custom UI on top."],"tags":["protocol","unsupported-feature","text-transfer","metadata"],"backgroundTag":null,"analyzedSha":"e25f1bdc04f07f094d50b0a1bf67e2563944b57a","analyzedAt":"2026-08-15T12:53:39.096Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}