garrytan/gstack · error · Error
Invalid file URL: file://~/ would list the home directory. U
Error message
Invalid file URL: file://~/ would list the home directory. Use file://~/<filename> to render a specific file.
What it means
Thrown by normalizeFileUrl when the input is `file://~` or `file://~/` — the file scheme with `~` as the authority and no filename. Like the `.` case, this would trigger a directory listing of the home directory, so the library demands an explicit filename.
Source
Thrown at browse/src/url-validation.ts:174
return pathPart + trailing;
}
// Everything else: must start with // (we accept file://... only)
if (!rest.startsWith('//')) {
throw new Error(`Invalid file URL: ${url}. Use file:///<absolute-path> or file://./<rel> or file://~/<rel>.`);
}
const afterDoubleSlash = rest.slice(2);
// Reject empty (file://) and trailing-slash-only (file://./ listing cwd).
if (afterDoubleSlash === '') {
throw new Error('Invalid file URL: file:// is empty. Use file:///<absolute-path>.');
}
if (afterDoubleSlash === '.' || afterDoubleSlash === './') {
throw new Error('Invalid file URL: file://./ would list the current directory. Use file://./<filename> to render a specific file.');
}
if (afterDoubleSlash === '~' || afterDoubleSlash === '~/') {
throw new Error('Invalid file URL: file://~/ would list the home directory. Use file://~/<filename> to render a specific file.');
}
// Home-relative: file://~/<rel>
if (afterDoubleSlash.startsWith('~/')) {
const rel = afterDoubleSlash.slice(2);
const absPath = path.join(os.homedir(), rel);
return pathToFileURL(absPath).href + trailing;
}
// cwd-relative with explicit ./ : file://./<rel>
if (afterDoubleSlash.startsWith('./')) {
const rel = afterDoubleSlash.slice(2);
const absPath = path.resolve(process.cwd(), rel);
return pathToFileURL(absPath).href + trailing;
}
// localhost host explicitly allowed: file://localhost/<abs> (pass through to standard parser).
if (afterDoubleSlash.toLowerCase().startsWith('localhost/')) {View on GitHub (pinned to 94993f7401)
Solutions
- Always include the filename: `file://~/Documents/report.html`.
- When constructing from `~` + filename, default the filename if empty.
- Prefer pathToFileURL(path.join(os.homedir(), filename)).href for programmatic construction.
Example fix
// before
await goto(`file://~/${name}`); // name empty → file://~/
// after
const file = name || 'index.html';
await goto(`file://~/${file}`); Defensive patterns
Strategy: validation
Validate before calling
function requireHomeFilename(u: string): void {
const lower = u.toLowerCase();
if (lower === 'file://~' || lower === 'file://~/') {
throw new Error('file://~/ requires a filename');
}
} Type guard
const hasHomeRelativeFilename = (u: string): boolean => {
const m = /^file:\/\/~\/(.+)$/i.exec(u);
return !!m && m[1].length > 0;
}; Try / catch
try {
await goto(url);
} catch (e: any) {
if (/file:\/~\/ would list/.test(e.message)) {
await goto(`file://~/index.html`);
} else throw e;
} Prevention
- Always join a filename onto the `file://~/` prefix.
- Build home-relative URLs with pathToFileURL(path.join(os.homedir(), file)).href.
- Default to index.html when the filename is missing.
- Validate basename non-empty before constructing the URL.
When it happens
Trigger: Calling goto with `file://~/` (trailing slash, no filename); building a URL as `file://~/${rest}` where rest is empty.
Common situations: A user trying to 'browse my home folder'; a fixture loader using `~` as a base and joining an empty filename; a docs example that trimmed the final path segment.
Related errors
- Invalid file URL: file:/// has no path. Use file:///<absolut
- Invalid file URL: file://./ would list the current directory
- Invalid file URL: ${url}. Use file:///<absolute-path> or fil
- Invalid file URL: file:// is empty. Use file:///<absolute-pa
- Unsupported file URL host: ${segment}. Use file:///<absolute
AI-assisted analysis of garrytan/gstack@94993f7401 (2026-08-12).
Data as JSON: /api/errors/d6a3c67e0f27db08.
Report an issue: GitHub.