denoland/deno · error · Error
${prefix}Linter plugin name must be a string
Error message
${prefix}Linter plugin name must be a string What it means
During bundle-identifier rewriting on macOS, each helper application's Info.plist is read to derive a new `CFBundleIdentifier` from the existing value's `helper` suffix. This error means a helper plist is missing that key entirely (or holds a non-string value), so no new id can be computed.
Source
Thrown at cli/js/40_lint.js:486
return plugins.map((plugin, i) => installPlugin(plugin, specifiers?.[i]));
}
/**
* @param {Deno.lint.Plugin} plugin
* @param {string} [specifier] The specifier the plugin was loaded from, if any.
*/
function installPlugin(plugin, specifier) {
// When the plugin was loaded from a specifier (i.e. `lint.plugins` in the
// config), prefix validation errors with it so the user knows which plugin
// is misbehaving instead of getting an anonymous error.
const prefix = typeof specifier === "string"
? `Failed to load lint plugin '${specifier}': `
: "";
if (typeof plugin !== "object") {
throw new Error(`${prefix}Linter plugin must be an object`);
}
if (typeof plugin.name !== "string") {
throw new Error(`${prefix}Linter plugin name must be a string`);
}
if (!/^[a-z-]+$/.test(plugin.name)) {
throw new Error(
`${prefix}Linter plugin name must only contain lowercase letters (a-z) or hyphens (-).`,
);
}
if (plugin.name.startsWith("-") || plugin.name.endsWith("-")) {
throw new Error(
`${prefix}Linter plugin name must start and end with a lowercase letter.`,
);
}
if (plugin.name.includes("--")) {
throw new Error(
`${prefix}Linter plugin name must not have consequtive hyphens.`,
);
}
if (typeof plugin.rules !== "object") {
throw new Error(`${prefix}Linter plugin rules must be an object`);View on GitHub (pinned to 89f33cbef2)
Solutions
- Restore the original helper Info.plist by rebuilding or re-downloading the bundle (clear the laufey cache)
- If you edited plists yourself, re-add `CFBundleIdentifier` with the original value
- Update Deno / clear the cache if the shipped archive is the likely cause
- Report a bug if untouched, freshly downloaded bundles trigger it
Defensive patterns
Strategy: validation
Validate before calling
const dict = parsePlist(await Deno.readTextFile(helperPlistPath));
if (typeof dict['CFBundleIdentifier'] !== 'string') {
throw new Error('helper plist lacks CFBundleIdentifier — rebuild or re-download the bundle');
} Type guard
interface HelperPlist { CFBundleIdentifier?: string }
function hasBundleId(p: HelperPlist): p is HelperPlist & { CFBundleIdentifier: string } {
return typeof p.CFBundleIdentifier === 'string' && p.CFBundleIdentifier.length > 0;
} Prevention
- Do not hand-edit generated helper Info.plist files; keep originals backed up
- After regenerating bundles, verify every helper plist still has CFBundleIdentifier
- Keep Deno updated so plist expectations match the shipped laufey archives
When it happens
Trigger: Helper Info.plist files that were manually edited, stripped, or replaced in the bundle; or a laufey archive revision whose helper plists renamed/removed the key (version skew with this Deno).
Common situations: Users customizing generated app bundles (renaming helpers, minifying plists); a backend archive from a newer laufey than the Deno build expects.
Related errors
- The bench function must have a name
- Unexpected second argument to Deno.bench()
- Unexpected 'fn' field in options, bench function is already
- Either `node` or `range` must be provided when reporting an
- Invalid range. Start value is bigger than end value: [${star
AI-assisted analysis of denoland/deno@89f33cbef2 (2026-08-16).
Data as JSON: /api/errors/62aed8c650f9945b.
Report an issue: GitHub.