schollz/croc · error · Error
Remote filename is empty
Error message
Remote filename is empty
What it means
normalizeFilePath() throws when the single name segment is empty — i.e. the filename normalizes to nothing (empty string, '.', or a bare '/'). A file with no name cannot be saved, so the offer is rejected before any destination path is built.
Source
Thrown at web/src/protocol/metadata.ts:43
if (/^(?:[a-zA-Z]:|\/)/.test(value)) {
throw new Error(`Remote path must be relative: ${value}`);
}
const segments = cleanSegments(value);
const normalized = segments.join("/") || ".";
if (normalized.includes(".ssh")) {
throw new Error(`Remote path is not allowed: ${value}`);
}
return normalized;
}
export function normalizeFilePath(folderValue: string, nameValue: string) {
const folder = normalizeFolder(folderValue);
const nameSegments = cleanSegments(nameValue);
if (nameSegments.length !== 1 || nameSegments[0] !== nameValue.replaceAll("\\", "/")) {
throw new Error(`Remote filename must be a basename: ${nameValue}`);
}
const name = nameSegments[0];
if (!name) throw new Error("Remote filename is empty");
const path = folder === "." ? name : `${folder}/${name}`;
return { folder, name, path };
}
export function normalizeOutgoingFileName(value: string) {
// Go's unicode.IsPrint accepts ASCII space but rejects the other Unicode
// separator characters commonly inserted into filenames by macOS.
const compatible = value.replace(/\p{Z}+/gu, " ");
return normalizeFilePath(".", compatible).name;
}
function finiteSize(file: WireFileInfo) {
const size = file.s ?? 0;
if (!Number.isSafeInteger(size) || size < 0) {
throw new Error(`Invalid file size for ${file.n ?? "unnamed file"}`);
}
return size;
}View on GitHub (pinned to e25f1bdc04)
Solutions
- Ensure every file entry in the offer has a real basename in the 'n' field.
- On the sender, derive names with path splitting that cannot return '' (guard against trailing slashes).
- As a receiver, refuse offers that fail here — there is no sensible default filename to substitute safely.
Defensive patterns
Strategy: validation
Validate before calling
function hasNonEmptyBasename(value: string): boolean {
const replaced = value.replaceAll("\\", "/").replace(/\/+$/, "");
return replaced !== "" && replaced !== ".";
} Try / catch
try {
const { name } = normalizeFilePath(folder, candidateName);
} catch (error) {
if (error instanceof Error && error.message === "Remote filename is empty") {
rejectOffer("file entry has no name");
return;
}
throw error;
} Prevention
- Require a non-empty 'n' field on every offered file before sending.
- Guard path-splitting helpers so they never return '' for directory-like inputs.
- Do not invent default filenames for unnamed remote entries — reject them.
When it happens
Trigger: normalizeFilePath(folder, '') — typically an offered file whose wire 'n' field is missing (wire.n ?? '' fallback in validateSenderInfo) or is '.' or '/'. Also reachable via normalizeOutgoingFileName('') or ('.').
Common situations: Hostile/buggy peer omitting the name field; sender code building offers with an empty filename (e.g. path.basename returning '' for directory-like inputs); a directory entry mistakenly listed in FilesToTransfer.
Related errors
- A remote path contains a null byte
- Remote path escapes the destination: ${value}
- Remote path contains a non-printable character: ${value}
- Remote path must be relative: ${value}
- Remote path is not allowed: ${value}
AI-assisted analysis of schollz/croc@e25f1bdc04 (2026-08-15).
Data as JSON: /api/errors/96b82bcd3e081564.
Report an issue: GitHub.