{"record":{"id":"ea0425e3fafd738b","repo":"denoland/deno","slug":"missing-name","errorCode":null,"errorMessage":"Missing name","messagePattern":"Missing name","errorType":"exception","errorClass":"AnyError","httpStatus":null,"severity":"error","filePath":"cli/tools/pack/npm_tarball.rs","lineNumber":27,"sourceCode":"\nuse super::AssetFile;\nuse super::ProcessedFile;\nuse super::ReadmeOrLicense;\nuse super::extensions::js_to_dts_extension;\n\n/// Compute the default tarball filename (`scope-name-version.tgz`) that\n/// `pack` writes when no `--output` is given. Extracted so the asset\n/// collector can exclude this exact path (instead of guessing by `.tgz`\n/// extension) and so the name is computed in exactly one place.\npub fn default_tarball_filename(\n  config_file: &ConfigFile,\n  version: &str,\n) -> Result<PathBuf, AnyError> {\n  let name = config_file\n    .json\n    .name\n    .as_ref()\n    .ok_or_else(|| deno_core::anyhow::anyhow!(\"Missing name\"))?;\n  // Convert @scope/name to scope-name\n  let normalized = name.replace('@', \"\").replace('/', \"-\");\n  // The package name shape is checked against `@scope/name` higher up\n  // (see `pack` in mod.rs), but that check is loose — it does not\n  // forbid path-traversal sequences. Treat this as a hard safety\n  // boundary right before we open a file, rejecting any derived\n  // tarball name that contains `..` or path separators so we never\n  // escape the cwd regardless of upstream validation drift.\n  if normalized.contains(\"..\") || normalized.contains('/') {\n    return Err(deno_core::anyhow::anyhow!(\n      \"refusing to write tarball with unsafe name derived from package: {}\",\n      name\n    ));\n  }\n  Ok(PathBuf::from(format!(\"{}-{}.tgz\", normalized, version)))\n}\n\n/// Tar archive paths must use forward slashes, even on Windows. Output paths","sourceCodeStart":9,"sourceCodeEnd":45,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/cli/tools/pack/npm_tarball.rs#L9-L45","documentation":"`deno pack` derives the default tarball filename as `<name>-<version>.tgz` from deno.json's `name` field (default_tarball_filename is the single place this is computed). A config without `name` leaves nothing to derive the filename from, so pack fails before writing anything.","triggerScenarios":"Running `deno pack` where deno.json has no `name` entry — e.g. a workspace root config that only holds tasks and imports, or a script project created by `deno init` without publish metadata.","commonSituations":"Workspace root configs used purely for task definitions; name/version defined only in a member config while running pack at the root; hand-rolled configs missing publish fields.","solutions":["Add `\"name\"` and `\"version\"` to deno.json: `\"name\": \"my-pkg\", \"version\": \"1.0.0\"`","For scoped packages use `\"name\": \"@scope/my-pkg\"` (normalized to scope-my-pkg)","Run pack from the workspace member whose config actually defines the package"],"exampleFix":"// before (deno.json)\n{ \"tasks\": { \"dev\": \"deno run main.ts\" } }\n\n// after\n{\n  \"name\": \"@scope/my-pkg\",\n  \"version\": \"1.0.0\",\n  \"tasks\": { \"dev\": \"deno run main.ts\" }\n}","handlingStrategy":"validation","validationCode":"const config = JSON.parse(await Deno.readText('deno.json'));\nif (typeof config.name !== 'string' || config.name.length === 0) {\n  throw new Error('deno.json needs a \"name\" before deno pack');\n}","typeGuard":"interface NamedConfig { name: string; version: string }\nconst isNamedConfig = (c: unknown): c is NamedConfig =>\n  !!c && typeof (c as any).name === 'string' &&\n  typeof (c as any).version === 'string';","tryCatchPattern":null,"preventionTips":["Add name/version as soon as a project might ever be packed","Validate config fields in pre-pack CI steps","Keep publish metadata in the member config, not only the workspace root"],"tags":["pack","deno-json","package-name","publishing"],"backgroundTag":"missing-package-name","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","contentChangedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}