schollz/croc · error
Invalid stored-transfer URL
Error message
Invalid stored-transfer URL
What it means
The URL branch of parseStoredShare() demands a strict share URL shape: pathname exactly /s/<22 base64url chars>, no username/password, no query string, and a fragment beginning with #v1.. Anything else — wrong path, a ?query appended, missing or wrong-prefixed key fragment — throws.
Source
Thrown at web/src/protocol/stored.ts:193
if (trimmed.startsWith(`${storedProtocol}.`)) {
const parts = trimmed.split(".");
if (parts.length !== 4) throw new Error("Invalid stored-transfer token");
return validateShare({
origin: textDecoder.decode(fromBase64URL(parts[1])),
id: parts[2],
key: fromBase64URL(parts[3]),
});
}
const parsed = new URL(trimmed);
const match = parsed.pathname.match(/^\/s\/([A-Za-z0-9_-]{22})$/);
if (
!match ||
parsed.username ||
parsed.password ||
parsed.search ||
!parsed.hash.startsWith("#v1.")
) {
throw new Error("Invalid stored-transfer URL");
}
return validateShare({
origin: parsed.origin,
id: match[1],
key: fromBase64URL(parsed.hash.slice(4)),
});
}
export function storedShareFromLocation(location: Location = window.location) {
if (!/^\/s\/[A-Za-z0-9_-]{22}$/.test(location.pathname)) return undefined;
if (!location.hash.startsWith("#v1.")) return undefined;
return parseStoredShare(location.href);
}
export function isStoredShareValue(value: string) {
const trimmed = value.trim();
if (trimmed.startsWith(`${storedProtocol}.`)) return true;
try {View on GitHub (pinned to e25f1bdc04)
Solutions
- Use the pristine link generated by the sender — no trackers, no extra path, and the #v1. key fragment intact
- Strip query strings and normalize the path before parsing if you must accept wrapped URLs
- Detect share-shaped input first with isStoredShareValue() or storedShareFromLocation() to give a friendly prompt instead of an exception
Example fix
// before
const share = parseStoredShare(input); // throws if input has ?utm_source=...
// after
const cleaned = input.trim().replace(/[?#].*$/, (m) => (m.startsWith("#v1.") ? m : ""));
const share = parseStoredShare(cleaned); Defensive patterns
Strategy: validation
Validate before calling
const looksLikeShareURL = (v: string): boolean => { try { const u = new URL(v.trim()); return /^\/s\/[A-Za-z0-9_-]{22}$/.test(u.pathname) && u.hash.startsWith("#v1.") && !u.username && !u.password && !u.search; } catch { return false; } }; Prevention
- Strip tracking query params and verify the #v1. fragment exists before parsing
- Use storedShareFromLocation() on the receive page instead of re-parsing arbitrary strings
When it happens
Trigger: parseStoredShare("https://host/s/ID?utm=...") — query string present; a URL without the #v1. key fragment; a path like /share/ID or /s/ID/extra; a URL with embedded credentials.
Common situations: Share links run through analytics/redirect wrappers that append query parameters; users sharing the URL without the fragment (fragments are often stripped when links are re-shared in some clients); typos in the path.
Related errors
- Stored-transfer origin must contain only an HTTPS scheme and
- Invalid stored-transfer token
- Code must be at least 6 characters
- Custom codes must use printable ASCII characters
- Choose at least one file
AI-assisted analysis of schollz/croc@e25f1bdc04 (2026-08-15).
Data as JSON: /api/errors/eba95a3a6c82f0f2.
Report an issue: GitHub.