apache/cordova-android · error · CordovaError
Destination "${dest}" for source file "${src}" is located ou
Error message
Destination "${dest}" for source file "${src}" is located outside the project What it means
The destination-side guard in copyFile: the resolved destination must be inside the project directory. A target/target-dir attribute containing ../ or an absolute path resolves outside platforms/android and the copy is refused with this CordovaError, protecting the filesystem from plugins writing outside the Cordova project.
Source
Thrown at lib/pluginHandlers.js:220
return handlers[type].uninstall;
}
events.emit('verbose', '<' + type + '> is not supported for android plugins');
};
function copyFile (plugin_dir, src, project_dir, dest, link) {
src = path.resolve(plugin_dir, src);
if (!fs.existsSync(src)) throw new CordovaError('"' + src + '" not found!');
// check that src path is inside plugin directory
const real_path = fs.realpathSync(src);
const real_plugin_path = fs.realpathSync(plugin_dir);
if (!isPathInside(real_path, real_plugin_path)) { throw new CordovaError('File "' + src + '" is located outside the plugin directory "' + plugin_dir + '"'); }
dest = path.resolve(project_dir, dest);
// check that dest path is located in project directory
if (!isPathInside(dest, project_dir)) { throw new CordovaError('Destination "' + dest + '" for source file "' + src + '" is located outside the project'); }
fs.mkdirSync(path.dirname(dest), { recursive: true });
if (link) {
symlinkFileOrDirTree(src, dest);
} else {
fs.cpSync(src, dest, { recursive: true });
}
}
// Same as copy file but throws error if target exists
function copyNewFile (plugin_dir, src, project_dir, dest, link) {
const target_path = path.resolve(project_dir, dest);
if (fs.existsSync(target_path)) { throw new CordovaError('"' + target_path + '" already exists!'); }
copyFile(plugin_dir, src, project_dir, dest, !!link);
}
function symlinkFileOrDirTree (src, dest) {View on GitHub (pinned to 7c1e190064)
Solutions
- Change target-dir/target to a path relative to the Android project root without leading slash or ../, e.g. target-dir="src/com/example/plugin"
- Verify what the project root is for the element type (source-file: app/src/main/java...; resource-file: app/src/main/res...)
- Treat this error in a third-party plugin as a red flag: inspect its plugin.xml before working around it
Example fix
<!-- before --> <resource-file src="hosts" target="/etc/hosts" /> <!-- after --> <resource-file src="hosts" target="app/src/main/res/raw/hosts" />
Defensive patterns
Strategy: validation
Validate before calling
// target-dir/target must be relative and must not escape the project
const safe = t => !path.isAbsolute(t) && !t.split('/').includes('..');
if (!safe(targetDirAttr)) throw new Error('target escapes the Cordova project and will be rejected'); Try / catch
try { await cordova.plugin('add', p); } catch (e) {
if (/located outside the project/.test(e.message)) { /* fix target/target-dir to a project-relative path */ }
} Prevention
- Write target-dir relative to the Android platform project (no leading /)
- Treat absolute targets in third-party plugins as malicious and inspect them
When it happens
Trigger: A plugin.xml element like <source-file src="x.java" target-dir="../../somewhere"/> or a target attribute resolving outside projectDir; also resource-file target="res/../../etc/hosts"-style paths. Thrown during `cordova plugin add` / `cordova prepare`.
Common situations: Plugin author mistakenly writes an install-absolute path (target-dir="/src/com/x") which path.resolve treats as absolute and escapes the project; ported iOS-style target paths; malicious or buggy third-party plugin.
Related errors
- File "${src}" is located outside the plugin directory "${plu
- Required attribute "src" not specified in <framework> elemen
- Required attribute "src" not specified in <asset> element fr
- Required attribute "target" not specified in <asset> element
- "${src}" not found!
AI-assisted analysis of apache/cordova-android@7c1e190064 (2026-08-22).
Data as JSON: /api/errors/17fa486b85a61483.
Report an issue: GitHub.