{"record":{"id":"6b6d5cf8c1fd7640","repo":"schollz/croc","slug":"invalid-stored-transfer-token","errorCode":null,"errorMessage":"Invalid stored-transfer token","messagePattern":"Invalid stored-transfer token","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"web/src/protocol/stored.ts","lineNumber":177,"sourceCode":"  validateShare(share);\n  return `${share.origin}/s/${share.id}#v1.${base64URL(share.key)}`;\n}\n\nexport function formatStoredCLIToken(share: StoredShare) {\n  validateShare(share);\n  return [\n    storedProtocol,\n    base64URL(textEncoder.encode(share.origin)),\n    share.id,\n    base64URL(share.key),\n  ].join(\".\");\n}\n\nexport function parseStoredShare(value: string): StoredShare {\n  const trimmed = value.trim();\n  if (trimmed.startsWith(`${storedProtocol}.`)) {\n    const parts = trimmed.split(\".\");\n    if (parts.length !== 4) throw new Error(\"Invalid stored-transfer token\");\n    return validateShare({\n      origin: textDecoder.decode(fromBase64URL(parts[1])),\n      id: parts[2],\n      key: fromBase64URL(parts[3]),\n    });\n  }\n  const parsed = new URL(trimmed);\n  const match = parsed.pathname.match(/^\\/s\\/([A-Za-z0-9_-]{22})$/);\n  if (\n    !match ||\n    parsed.username ||\n    parsed.password ||\n    parsed.search ||\n    !parsed.hash.startsWith(\"#v1.\")\n  ) {\n    throw new Error(\"Invalid stored-transfer URL\");\n  }\n  return validateShare({","sourceCodeStart":159,"sourceCodeEnd":195,"githubUrl":"https://github.com/schollz/croc/blob/e25f1bdc04f07f094d50b0a1bf67e2563944b57a/web/src/protocol/stored.ts#L159-L195","documentation":"parseStoredShare() splits a croc-store-v1 token on '.' and requires exactly 4 segments: protocol, base64url origin, id, base64url key. Extra dots (e.g., inside a hostname-less or mis-pasted token) or missing segments produce this error before any segment is decoded.","triggerScenarios":"Calling parseStoredShare with a string starting with \"croc-store-v1.\" whose split('.').length !== 4 — e.g. trailing period, an origin segment containing a literal '.', or a token truncated/concatenated with other text.","commonSituations":"Note that valid origins like \"https://example.com\" contain no dots after encoding? They do not (base64url alphabet has none), but a user pasting two tokens together, adding punctuation, or a markdown renderer auto-linking the token and appending a period all hit this.","solutions":["Re-copy the token verbatim; ensure no trailing punctuation or adjacent text got included","Validate shape first: value.trim().startsWith(\"croc-store-v1.\") && value.split(\".\").length === 4","Accept the browser URL form (https://host/s/<id>#v1.<key>) as the canonical paste format; it is dot-free"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"const isWellFormedToken = (v: string): boolean => v.trim().startsWith(\"croc-store-v1.\") && v.trim().split(\".\").length === 4;","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Trim surrounding whitespace and punctuation from pasted tokens","Use isStoredShareValue() to gate input fields before attempting parseStoredShare"],"tags":["validation","token","parsing"],"backgroundTag":null,"analyzedSha":"e25f1bdc04f07f094d50b0a1bf67e2563944b57a","analyzedAt":"2026-08-15T12:53:39.096Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}