{"record":{"id":"745b667dc94c301e","repo":"denoland/deno","slug":"the-source-path-is-not-a-valid-file","errorCode":null,"errorMessage":"the source path is not a valid file","messagePattern":"the source path is not a valid file","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"ext/fs/std_fs.rs","lineNumber":905,"sourceCode":"      //   && source_meta.volume_serial_number()\n      //     == dest_meta.volume_serial_number()\n      source_meta.last_write_time() == dest_meta.last_write_time()\n        && source_meta.creation_time() == dest_meta.creation_time()\n    }\n  }\n\n  if let Ok(m) = fs::metadata(to)\n    && m.is_dir()\n  {\n    // Only target sub dir when source is not a dir itself\n    if let Ok(from_meta) = fs::metadata(from)\n      && !from_meta.is_dir()\n    {\n      return cp_(\n        source_meta,\n        from,\n        &to.join(from.file_name().ok_or_else(|| {\n          io::Error::new(\n            io::ErrorKind::InvalidInput,\n            \"the source path is not a valid file\",\n          )\n        })?),\n      );\n    }\n  }\n\n  if let Ok(m) = fs::symlink_metadata(to)\n    && is_identical(&source_meta, &m)\n  {\n    return Err(\n      io::Error::new(\n        io::ErrorKind::InvalidInput,\n        \"the source and destination are the same file\",\n      )\n      .into(),\n    );","sourceCodeStart":887,"sourceCodeEnd":923,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/ext/fs/std_fs.rs#L887-L923","documentation":"In Deno.copy()/copySync(), when the destination is an existing directory and the source is not a directory, Deno copies into dest/from.file_name(). If the source path has no final component — it terminates in '..' or is a filesystem root — file_name() returns None and the copy fails with io::ErrorKind::InvalidInput 'the source path is not a valid file' (ext/fs/std_fs.rs:905).","triggerScenarios":"A source path whose literal form ends in '..' (e.g. 'data/..') or is a root ('/') while the destination exists as a directory and fs::metadata resolves the source to a non-directory (reachable mainly through symlink chains, since a literal '..' usually resolves to a directory).","commonSituations":"Path-joining bugs that append '..' to a source; passing a resolved parent or cwd as the source; scripts assembling paths from user input without normalization.","solutions":["Normalize the source with Deno.realPathSync(from) before copying","Validate the source has a real file-name component: from.split('/').pop() not in ['', '.', '..']","Handle directories and files with separate branches instead of relying on dest-dir dispatch"],"exampleFix":"// before\nDeno.copySync(`${dir}/..`, destDir);\n\n// after\nconst from = Deno.realPathSync(dir);\nDeno.copySync(from, destDir);","handlingStrategy":"validation","validationCode":"function normalizeCopySource(from: string): string {\n  const real = Deno.realPathSync(from); // resolves '..' and symlink segments\n  const name = real.split('/').pop() ?? '';\n  if (name === '' || name === '.' || name === '..') {\n    throw new Error(`Copy source has no file-name component: ${from}`);\n  }\n  return real;\n}","typeGuard":"function hasFileNameComponent(p: string): boolean {\n  const name = p.split('/').pop() ?? '';\n  return name !== '' && name !== '.' && name !== '..';\n}","tryCatchPattern":null,"preventionTips":["Normalize source paths with realPathSync before Deno.copy","Never assemble copy sources by appending '..'","Handle directories and files in separate branches instead of relying on dest-dir dispatch"],"tags":["filesystem","copy","path","invalid-input","deno"],"backgroundTag":"invalid-file-path","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-08-31T09:17:48.483Z"}