schollz/croc · error · Error
Remote filename must be a basename: ${nameValue}
Error message
Remote filename must be a basename: ${nameValue} What it means
normalizeFilePath() requires the file's name to be a single path segment: after backslash→slash replacement, cleanSegments(name) must yield exactly one segment equal to the replaced name. Any '/', multiple segments, or trailing slash (which would leave an empty final segment) fails this basename invariant.
Source
Thrown at web/src/protocol/metadata.ts:40
}
export function normalizeFolder(value = ".") {
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"}`);View on GitHub (pinned to e25f1bdc04)
Solutions
- Split the path yourself: put directories in the folder argument and the last segment in name — normalizeFilePath('docs', 'file.txt').
- Strip trailing slashes from names before offering.
- Reject offers from peers whose file names contain separators (they should use fr for folders).
Example fix
// before
normalizeFilePath(".", "docs/file.txt");
// after
normalizeFilePath("docs", "file.txt"); Defensive patterns
Strategy: validation
Validate before calling
function isBasename(value: string): boolean {
const replaced = value.replaceAll("\\", "/");
return replaced.length > 0 && !replaced.includes("/");
}
if (!isBasename(nameValue)) throw new TypeError(`not a basename: ${nameValue}`); Try / catch
try {
const { path } = normalizeFilePath(folder, name);
} catch (error) {
if (error instanceof Error && error.message.startsWith("Remote filename must be a basename")) {
// split folder/name yourself and retry, or reject the offer
const idx = name.lastIndexOf("/");
return normalizeFilePath(`${folder}/${name.slice(0, idx)}`, name.slice(idx + 1));
}
throw error;
} Prevention
- Always split paths into (folder, basename) on the sender; keep 'n' a single segment.
- Strip trailing slashes from names before offering.
- Treat separator-containing names from peers as malformed metadata.
When it happens
Trigger: Calling normalizeFilePath(folder, name) with name='docs/file.txt', name='a/', name='dir/' (trailing slash yields a segment list mismatch or empty last segment), or any name containing separators. Reached from validateSenderInfo for each offered file and from normalizeOutgoingFileName.
Common situations: Sender-side code passing a full relative path as the filename instead of splitting folder/name; a hostile peer smuggling path components in n; sending a directory-shaped entry as a file; names ending in '/' from sloppy path joins.
Related errors
- Sender did not provide file metadata
- 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}
AI-assisted analysis of schollz/croc@e25f1bdc04 (2026-08-15).
Data as JSON: /api/errors/99b8446447342de0.
Report an issue: GitHub.