denoland/deno · error

bundle identifier {id:?} is longer than 155 characters

Error message

bundle identifier {id:?} is longer than 155 characters

What it means

Thrown by validate_bundle_identifier when `--identifier` exceeds 155 characters. 155 is Apple's documented limit for CFBundleIdentifier on receipts; longer values are silently truncated elsewhere in the toolchain (codesign, helpers), so Deno rejects them up front instead of letting later steps fail obscurely.

Source

Thrown at cli/tools/desktop.rs:2469

/// Validate a reverse-DNS bundle identifier (Apple `CFBundleIdentifier`,
/// also used for Linux `.desktop` filenames and Windows AppUserModelID).
///
/// Apple's rules: ASCII alphanumerics, hyphens, and dots; must have at
/// least one dot (so it looks like reverse DNS); each dot-separated
/// segment must be non-empty and not start with a digit. We don't
/// enforce the segment-leading-letter rule strictly (some legacy apps
/// use digits) but we do reject empty segments and obvious shell
/// metacharacters — the identifier ends up as a `codesign` argument and
/// a path component of the helper bundles.
fn validate_bundle_identifier(id: &str) -> Result<(), AnyError> {
  if id.is_empty() {
    bail!("bundle identifier is empty");
  }
  if id.len() > 155 {
    // Apple's documented limit for CFBundleIdentifier on receipts is
    // 155 chars; bigger values quietly truncate elsewhere in the
    // toolchain.
    bail!("bundle identifier {id:?} is longer than 155 characters");
  }
  if !id.contains('.') {
    bail!(
      "bundle identifier {id:?} must be in reverse-DNS form (e.g. com.acme.foo)"
    );
  }
  for c in id.chars() {
    if !(c.is_ascii_alphanumeric() || c == '.' || c == '-') {
      bail!(
        "bundle identifier {id:?} must match [A-Za-z0-9.-]+, but contains {c:?}",
      );
    }
  }
  if id.split('.').any(|seg| seg.is_empty()) {
    bail!("bundle identifier {id:?} has an empty segment");
  }
  Ok(())
}

View on GitHub (pinned to f7822238ca)

Solutions

  1. Shorten to ≤155 characters — drop appended hashes/branch names that do not need to be in the id.
  2. Keep the stable part (`com.acme.myapp`) and move build metadata elsewhere (version, build files), not into CFBundleIdentifier.
  3. Add a length assertion in the script that generates the identifier.

Example fix

# before
deno desktop --identifier "com.acme.enterprise.division.platform.teams.desktop.ci.build.a1b2c3d4e5f6..." main.ts

# after
deno desktop --identifier "com.acme.teams.desktop" main.ts
Defensive patterns

Strategy: validation

Validate before calling

# bash: cap generated identifiers
BUNDLE_ID="com.acme.teams.desktop${SUFFIX:+-$SUFFIX}"
(( ${#BUNDLE_ID} <= 155 )) || { echo "identifier too long (${#BUNDLE_ID})" >&2; exit 1; }
deno desktop --identifier "$BUNDLE_ID" main.ts

Type guard

// TypeScript
function isWithinBundleIdLengthLimit(id: string): boolean {
  return id.length <= 155;
}

Prevention

When it happens

Trigger: Programmatically generated identifiers that embed long paths, hashes, or CI job names (e.g. com.acme.ci.build.${sha256...}); concatenating extra suffixes onto an already-long company identifier.

Common situations: CI pipelines appending commit SHAs or branch slugs to the base id; deep corporate reverse-DNS prefixes plus descriptive app names crossing the limit; identifier assembled from several config fields without a length check.

Related errors


AI-assisted analysis of denoland/deno@f7822238ca (2026-08-20). Data as JSON: /api/errors/e0cd26a7a8a15d2a. Report an issue: GitHub.