denoland/deno · error
bundle identifier {id:?} must be in reverse-DNS form (e.g. c
Error message
bundle identifier {id:?} must be in reverse-DNS form (e.g. com.acme.foo) What it means
Thrown by validate_bundle_identifier when `--identifier` contains no dot. Apple expects a reverse-DNS form (at least one dot, like com.acme.foo); the identifier is also used for Linux .desktop filenames and Windows AppUserModelID, where the dotted form is the convention. A single bare word like `myapp` fails this check.
Source
Thrown at cli/tools/desktop.rs:2472
/// 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(())
}
/// Walk every `.app` under `Contents/Frameworks/` and rewrite its
/// `CFBundleIdentifier` so it's a strict suffix of `main_bundle_id`.View on GitHub (pinned to f7822238ca)
Solutions
- Use full reverse-DNS: `com.acme.myapp` (at least one dot required).
- If you have no company domain, a stable placeholder like `com.example.<appname>` or `io.github.<user>.<app>` works.
- Or omit `--identifier` entirely to use the synthesized `com.deno.desktop.<slug>`.
Example fix
# before deno desktop --identifier myapp main.ts # after deno desktop --identifier com.acme.myapp main.ts
Defensive patterns
Strategy: validation
Validate before calling
# bash: require reverse-DNS form
BUNDLE_ID="com.acme.myapp"
[[ "$BUNDLE_ID" == *.* ]] || { echo "identifier must contain a dot" >&2; exit 1; }
deno desktop --identifier "$BUNDLE_ID" main.ts Type guard
// TypeScript
function isReverseDnsLike(id: string): boolean {
return id.includes(".");
} Prevention
- Derive the identifier from a domain you control (com.acme.myapp).
- Or leave --identifier off and accept the synthesized com.deno.desktop.<slug>.
- Do not paste URLs or bare product names as the identifier.
When it happens
Trigger: `deno desktop --identifier myapp main.ts`; `--identifier MyApp`; identifiers written in Java-package style without dots after a rename; a value like `acme:` where the dot was lost to shell quoting.
Common situations: Devs used to Electron's `name` field or Android `appId` without dots passing a bare word; config migration where `com.acme.myapp` got truncated to its last segment; quoting typos splitting the string.
Related errors
- bundle identifier is empty
- bundle identifier {id:?} must match [A-Za-z0-9.-]+, but cont
- Invalid deep-link scheme {scheme:?}: {reason}.
- unknown --compress format '{other}' (use xz or zstd)
- bundle identifier {id:?} is longer than 155 characters
AI-assisted analysis of denoland/deno@f7822238ca (2026-08-20).
Data as JSON: /api/errors/be98e428f9934e29.
Report an issue: GitHub.