paperclipai/paperclip · error · Error

: invalid aliases

Error message

${row.slug}: invalid aliases

What it means

The app brand validation script throws this when a provider row's aliases are invalid: the aliases field is present but not an array, or it contains entries that are not strings or are empty/whitespace strings.

Solutions

  1. Make aliases an array of non-empty strings for the row named by the slug.
  2. Remove or fill in empty/whitespace alias entries.
  3. Ensure the field is spelled `aliases` and is a JSON array, not a single string.
  4. Re-run the validation script after editing.

Example fix

// before
"aliases": "Acme"
// after
"aliases": ["Acme", "Acme Corp"]
Defensive patterns

Strategy: validation

Validate before calling

const bad = manifest.providers.filter(r => !Array.isArray(r.aliases ?? []) || (r.aliases ?? []).some(a => typeof a !== 'string' || !a.trim()));
if (bad.length) throw new Error(`Invalid aliases for: ${bad.map(r => r.slug)}`);

Type guard

const hasValidAliases = (row) => (row.aliases ?? []).every(a => typeof a === 'string' && a.trim().length > 0);

Try / catch

try { validateManifest(manifest); } catch (e) {
  if (e.message.includes('invalid aliases')) {
    const slug = e.message.split(':')[0];
    console.error(`Aliases for ${slug} must be an array of non-empty strings`);
  } else throw e;
}

Prevention

When it happens

Trigger: Running validateManifest where row.aliases is a string instead of an array, an alias element is null/number/object, or an alias is "" or " ".

Common situations: Writing aliases: "Name" (singular string) instead of an array; a YAML/JSON edit introducing a null alias; trailing commas or template placeholders left unfilled.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


AI-assisted analysis of paperclipai/paperclip@3f1d897a7c (2026-09-18). Data as JSON: /api/errors/561e321e985ac998. Report an issue: GitHub.

Appendix: source

Thrown at scripts/app-brand-validation.mjs:35

    throw new Error(`${filename}: SVG requires a viewBox or intrinsic width and height`);
  }
  if (/<!DOCTYPE|<!ENTITY|<\?xml-stylesheet|&#|<\s*(?:[\w-]+:)?(?:script|foreignObject|image|feImage|iframe|object|embed|animate\w*|set|a)\b|\bon[\w-]+\s*=/i.test(svg)
    || /\b(?:[\w-]+:)?href\s*=\s*["'](?!#)/i.test(svg)
    || /@import|@media|url\(\s*["']?(?!#)[^)]*\)|(?:javascript|data|https?):|\\/i.test(svg.replace(/xmlns(?::[\w-]+)?\s*=\s*["'][^"']*["']/gi, ""))) {
    throw new Error(`${filename}: unsafe SVG feature, external resource, theme media query, or embedded raster wrapper`);
  }
}

export function validateManifest(manifest, readAsset) {
  if (manifest.schemaVersion !== 1 || !Array.isArray(manifest.providers)) throw new Error("Invalid brand manifest");
  const keys = new Map();
  const slugs = new Set();
  for (const row of manifest.providers) {
    if (!/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(row.slug) || slugs.has(row.slug)) throw new Error(`Duplicate or invalid slug: ${row.slug}`);
    slugs.add(row.slug);
    if (typeof row.provider !== "string" || !row.provider.trim()) throw new Error(`${row.slug}: missing provider name`);
    const aliases = row.aliases ?? [];
    if (!Array.isArray(aliases) || aliases.some((alias) => typeof alias !== "string" || !alias.trim())) throw new Error(`${row.slug}: invalid aliases`);
    for (const name of [row.slug, row.provider, ...aliases]) {
      const key = normalizeBrandKey(name);
      if (keys.has(key) && keys.get(key) !== row.slug) throw new Error(`${row.slug}: ambiguous brand alias ${name}`);
      keys.set(key, row.slug);
    }
    for (const asset of new Set([row.localAsset, ...(row.darkAsset === undefined ? [] : [row.darkAsset])])) {
      if (typeof asset !== "string" || !assetPathPattern.test(asset)) throw new Error(`${row.slug}: invalid asset path`);
      validateArtwork(readAsset(asset), asset);
    }
  }
  return manifest.providers.length;
}

View on GitHub (pinned to 3f1d897a7c)