apache/cordova-android · error · CordovaError

"${target_path}" already exists!

Error message

"${target_path}" already exists!

What it means

copyNewFile (used for source-file, framework, etc. unless --force) refuses to overwrite: if the resolved destination already exists on disk it throws. It prevents a plugin install from silently clobbering files that already exist in the Android project, which usually means the plugin (or an older version of it) was installed before and not fully removed.

Source

Thrown at lib/pluginHandlers.js:233

    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) {
    if (fs.existsSync(dest)) {
        fs.rmSync(dest, { recursive: true, force: true });
    }

    if (fs.statSync(src).isDirectory()) {
        fs.mkdirSync(path.dirname(dest), { recursive: true });
        fs.readdirSync(src).forEach(function (entry) {
            symlinkFileOrDirTree(path.join(src, entry), path.join(dest, entry));
        });
    } else {
        fs.symlinkSync(path.relative(fs.realpathSync(path.dirname(dest)), src), dest);
    }
}

View on GitHub (pinned to 7c1e190064)

Solutions

  1. Remove the plugin cleanly first (`cordova plugin rm <id>`), delete any leftover target files it reports, then re-add
  2. Regenerate the platform if state is uncertain: `cordova platform rm android && cordova platform add android`
  3. Intentional overwrite? re-add with `cordova plugin add <id> --force` so copyFile is used instead of copyNewFile
  4. For your own plugin, give shared/generic files a namespaced target path (e.g. target-dir includes your package name) to avoid collisions with other plugins

Example fix

# before
cordova plugin add cordova-plugin-foo   # throws: file already exists

# after
cordova plugin rm cordova-plugin-foo
cordova platform rm android && cordova platform add android
cordova plugin add cordova-plugin-foo
# or, to allow overwriting:
cordova plugin add cordova-plugin-foo --force
Defensive patterns

Strategy: fallback

Validate before calling

// pre-flight: check whether the plugin's source-file targets already exist
const fs = require('fs'); const path = require('path');
const projectDir = 'platforms/android';
const exists = fs.existsSync(path.resolve(projectDir, targetDirAttr, path.basename(srcAttr)));
// if exists, choose --force or clean up leftovers before installing

Try / catch

try { await cordova.plugin('add', p); } catch (e) {
  if (/already exists!/.test(e.message)) { /* rm plugin / regenerate platform, or re-add with --force */ }
}

Prevention

When it happens

Trigger: `cordova plugin add` for a plugin whose <source-file> target path already exists: e.g. plugin added twice, a previous uninstall left files behind, or two plugins shipping a file with the same target-dir and name. Not thrown for resource-file/asset (those use plain copyFile and overwrite) nor when options.force is set.

Common situations: Re-adding a plugin after a failed uninstall or manual surgery on platforms/; upgrading a plugin whose files changed location; two plugins bundling the same support library source file; stale platforms/ directory after switching branches.

Related errors


AI-assisted analysis of apache/cordova-android@7c1e190064 (2026-08-22). Data as JSON: /api/errors/9c3357e59c117185. Report an issue: GitHub.