apache/cordova-android · error · CordovaError

Required attribute "target" not specified in <asset> element

Error message

Required attribute "target" not specified in <asset> element from plugin: ${plugin.id}

What it means

Thrown by the asset install handler when <asset> has src but no target attribute. target defines where inside the app's www directory the file lands; without it cordova-android cannot map the copy and rejects the plugin during install.

Source

Thrown at lib/pluginHandlers.js:135

                subDir = src;
            }

            if (obj.type === 'gradleReference') {
                project.removeGradleReference(parentDir, subDir);
            } else if (obj.type === 'sys') {
                project.removeSystemLibrary(parentDir, subDir);
            } else {
                project.removeSubProject(parentDir, subDir);
            }
        }
    },
    asset: {
        install: function (obj, plugin, project, options) {
            if (!obj.src) {
                throw new CordovaError(generateAttributeError('src', 'asset', plugin.id));
            }
            if (!obj.target) {
                throw new CordovaError(generateAttributeError('target', 'asset', plugin.id));
            }

            copyFile(plugin.dir, obj.src, project.www, obj.target);
            if (options && options.usePlatformWww) {
                // CB-11022 copy file to both directories if usePlatformWww is specified
                copyFile(plugin.dir, obj.src, project.platformWww, obj.target);
            }
        },
        uninstall: function (obj, plugin, project, options) {
            const target = obj.target || obj.src;

            if (!target) {
                throw new CordovaError(generateAttributeError('target', 'asset', plugin.id));
            }

            removeFileAndParents(project.www, target);
            if (options && options.usePlatformWww) {
                removeFileAndParents(project.platformWww, target);

View on GitHub (pinned to 7c1e190064)

Solutions

  1. Add target to every <asset> element: <asset src="www/foo.js" target="www/foo.js"/>
  2. Make sure target stays inside www (a leading slash or ../ in target will trip the path checks later)
  3. Fix and republish the plugin if it ships in this state

Example fix

<!-- before -->
<asset src="www/plugin-image.png" />

<!-- after -->
<asset src="www/plugin-image.png" target="www/img/plugin-image.png" />
Defensive patterns

Strategy: validation

Validate before calling

const fs = require('fs');
const xml = fs.readFileSync('node_modules/<plugin>/plugin.xml', 'utf8');
if (/<asset(?![^>]*\btarget=)[^>]*\/>/.test(xml)) {
  throw new Error('<asset> without target — fix plugin.xml before install');
}

Try / catch

try { await cordova.plugin('add', p); } catch (e) {
  if (/Required attribute "target" not specified in <asset>/.test(e.message)) { /* add target to asset elements */ }
}

Prevention

When it happens

Trigger: `cordova plugin add <plugin>` where plugin.xml contains <asset src="www/foo.js"/> with no target attribute. The handler checks src first, then throws generateAttributeError('target','asset',...) when !obj.target.

Common situations: Assuming src alone is enough (it is not on Android); copy-paste of <js-module> patterns where target does not exist; refactoring plugin.xml and losing the attribute.

Related errors


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