withastro/astro · error · Error
No files found to copy
Error message
No files found to copy
What it means
`copyFilesToFolder` in @astrojs/internal-helpers copies a list of traced files into a build output folder and throws immediately when the input array is empty — there is nothing to copy and no common ancestor to compute. In practice it is called by the Netlify and Vercel adapters' Node file-trace step (`lib/nft.ts`) to copy files that the server bundle references at runtime.
Solutions
- If calling the helper directly: check `files.length > 0` before invoking and skip the copy when empty
- On adapter builds: update @astrojs/vercel / @astrojs/netlify to the latest version compatible with your Astro version
- Verify the server entry was actually built (the build log should show SSR output) before the trace step
Example fix
// before
await copyFilesToFolder(files, outDir);
// after
if (files.length > 0) {
await copyFilesToFolder(files, outDir);
} Defensive patterns
Strategy: validation
Validate before calling
if (files.length === 0) {
console.warn('No traced files to copy; skipping copy step');
} else {
await copyFilesToFolder(files, outDir);
} Prevention
- Check list length before calling copy APIs that require non-empty input
- Keep adapter and Astro versions in lockstep so the trace step receives the files it expects
When it happens
Trigger: File tracing (via @vercel/nft) returns an empty set — e.g. the server entry produced no external file dependencies, or the tracing glob/copy step was fed an empty list during an adapter build. Direct callers hit it by passing an empty array, typically the result of a glob that matched nothing.
Common situations: Building with the Netlify/Vercel adapter where everything is bundled and no external files need copying; adapter version mismatches after upgrading Astro; scripts using this helper with a filtered file list that ends up empty. (Note: the guard checks `files.length`, not the post-exclusion list, so excluding every file produces a different downstream failure, not this error.)
Related errors
- This project contains server-rendered routes, but no…
- AdapterSupportOutputMismatch
- `Astro.session` was accessed but no session storage is…
- CannotDetermineWeightAndStyleFromFontFile
- CannotFetchFontFile
AI-assisted analysis of withastro/astro@52e6c34790 (2026-08-18).
Data as JSON: /api/errors/c13e1e0331b730c7.
Report an issue: GitHub.
Appendix: source
Thrown at packages/internal-helpers/src/fs.ts:51
/**
* Copies files into a folder keeping the folder structure intact.
* The resulting file tree will start at the common ancestor.
*
* @param {URL[]} files A list of files to copy (absolute path).
* @param {URL} outDir Destination folder where to copy the files to (absolute path).
* @param {URL[]} [exclude] A list of files to exclude (absolute path).
* @returns {Promise<string>} The common ancestor of the copied files.
*/
export async function copyFilesToFolder(
files: URL[],
outDir: URL,
exclude: URL[] = [],
): Promise<string> {
const excludeList = exclude.map((url) => fileURLToPath(url));
const fileList = files.map((url) => fileURLToPath(url)).filter((f) => !excludeList.includes(f));
if (files.length === 0) throw new Error('No files found to copy');
let commonAncestor = nodePath.dirname(fileList[0]);
for (const file of fileList.slice(1)) {
while (!file.startsWith(commonAncestor)) {
commonAncestor = nodePath.dirname(commonAncestor);
}
}
for (const origin of fileList) {
const dest = new URL(nodePath.relative(commonAncestor, origin), outDir);
const realpath = await fs.realpath(origin);
const isSymlink = realpath !== origin;
const isDir = (await fs.stat(origin)).isDirectory();
// Create directories recursively
if (isDir && !isSymlink) {
await fs.mkdir(new URL('..', dest), { recursive: true });View on GitHub (pinned to 52e6c34790)