{"record":{"id":"d33ff807a7903ddc","repo":"denoland/deno","slug":"invalid-kind-name-is-empty","errorCode":null,"errorMessage":"invalid {kind}: name is empty","messagePattern":"invalid (.+?): name is empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cli/tools/desktop.rs","lineNumber":2978,"sourceCode":"      dir.join(\"Release/laufey_webview.app\"),\n      dir.join(\"webview/Release/laufey_webview.app\"),\n    ],\n    _ => vec![\n      dir.join(format!(\"laufey_{backend}.app\")),\n      dir.join(\"laufey.app\"),\n    ],\n  };\n  candidates.into_iter().find(|p| p.exists())\n}\n\n/// Reject any name we'd interpolate into a generated launcher script\n/// (POSIX shell on macOS/Linux, `.bat` on Windows). Even the\n/// double-quoted positions take expansions: `$`, backticks, `\\` in\n/// bash; `%` and `^` in cmd.exe. The launcher kind context (`kind`)\n/// is included in the error to make the failure easy to act on.\nfn validate_launcher_name(name: &str, kind: &str) -> Result<(), AnyError> {\n  if name.is_empty() {\n    bail!(\"invalid {kind}: name is empty\");\n  }\n  // ASCII-only, alphanumerics + a small whitelist of harmless\n  // punctuation. Spaces are allowed because real macOS .app bundles\n  // commonly have spaces in their executable names.\n  let bad = name.chars().find(|c| {\n    !(c.is_ascii_alphanumeric() || matches!(c, ' ' | '.' | '_' | '-'))\n  });\n  if let Some(c) = bad {\n    bail!(\n      \"invalid {kind} {name:?}: must match [A-Za-z0-9 ._-]+, but contains {c:?}\",\n    );\n  }\n  Ok(())\n}\n\n/// The pieces of `dylib_path` we feed into the bundlers, with proper\n/// error messages instead of `unwrap` panics on degenerate inputs like\n/// `--output /` or `--output .`.","sourceCodeStart":2960,"sourceCodeEnd":2996,"githubUrl":"https://github.com/denoland/deno/blob/f7822238cab635a3a19f99f493f675fa81a7f9d8/cli/tools/desktop.rs#L2960-L2996","documentation":"validate_launcher_name guards every name that gets interpolated into generated launcher scripts (POSIX shell on macOS/Linux, .bat on Windows) — in practice the app name from your desktop config. The first check rejects an empty string before any escaping can be attempted, since an empty launcher name would produce a broken script.","triggerScenarios":"`deno desktop` runs with an app name that resolves to \"\" — e.g. the name field in the desktop config is present but empty, or a variable feeding it (CI env var, scaffold placeholder) was never filled in.","commonSituations":"Templated/scaffolded projects where someone left name empty; CI jobs templating deno.json from env vars that are unset.","solutions":["Set a non-empty app name in the desktop config (e.g. \"My App\").","If the name comes from a variable in CI, assert the variable is non-empty before invoking deno desktop."],"exampleFix":"// before\n\"desktop\": { \"name\": \"\" }\n\n// after\n\"desktop\": { \"name\": \"My App\" }","handlingStrategy":"validation","validationCode":"if (!config.desktop?.name || config.desktop.name.trim() === \"\") {\n  throw new Error(\"desktop.name is required and must be non-empty\");\n}","typeGuard":"function isValidLauncherName(name: unknown): name is string {\n  return typeof name === \"string\" && name.length > 0;\n}","tryCatchPattern":null,"preventionTips":["Fail CI on empty scaffold placeholders in deno.json before any build stage runs.","When injecting names from env vars, assert non-empty at job start."],"tags":["desktop","launcher","config-validation"],"backgroundTag":"empty-config-value","analyzedSha":"f7822238cab635a3a19f99f493f675fa81a7f9d8","analyzedAt":"2026-08-20T13:07:44.778Z","contentChangedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}