denoland/deno · error · AnyError

Missing name in config

Error message

Missing name in config

What it means

While generating the package.json payload for the packed tarball, generate_package_json() reads `name` from deno.json to embed in the output; a config without `name` fails here before any tarball is produced. It mirrors the tarball-filename check in npm_tarball.rs — both need the same field.

Solutions

  1. Add `"name": "my-pkg"` (or `"@scope/my-pkg"`) plus `"version"` to deno.json
  2. Run pack in the workspace member that owns the publish metadata
  3. Validate required publish fields in a pre-pack step so failures surface earlier

Example fix

// before (deno.json)
{ "version": "1.0.0" }

// after
{ "name": "@scope/my-pkg", "version": "1.0.0" }
Defensive patterns

Strategy: validation

Validate before calling

const config = JSON.parse(await Deno.readText('deno.json'));
if (typeof config.name !== 'string' || config.name.length === 0) {
  throw new Error('deno.json needs a "name" before deno pack');
}

Type guard

interface NamedConfig { name: string }
const isNamedConfig = (c: unknown): c is NamedConfig =>
  !!c && typeof (c as any).name === 'string' && (c as any).name.length > 0;

Prevention

When it happens

Trigger: Running `deno pack` with a deno.json that lacks a `name` field, so config_file.json.name is None at cli/tools/pack/package_json.rs:68 and the generated package.json would be nameless — invalid for npm consumers.

Common situations: Same shape as the tarball-name error: workspace root configs holding only tasks/imports; projects created as scripts and packed later; refactoring that moved `name` into a member config.

Related errors


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

Appendix: source

Thrown at cli/tools/pack/package_json.rs:68

  exports: Option<serde_json::Value>,
  // BTreeMap (not HashMap): serde_json walks BTreeMap in sorted key
  // order, so the generated package.json — and therefore the tarball
  // bytes — are identical across runs even with multiple deps. See the
  // `reproducible` spec test.
  #[serde(skip_serializing_if = "Option::is_none")]
  dependencies: Option<BTreeMap<String, String>>,
}

pub fn generate_package_json(
  config_file: &ConfigFile,
  version: &str,
  files: &[ProcessedFile],
) -> Result<String, AnyError> {
  let name = config_file
    .json
    .name
    .as_ref()
    .ok_or_else(|| deno_core::anyhow::anyhow!("Missing name in config"))?;

  let dts_set = dts_available_set(files);

  let exports = convert_exports(&config_file.json.exports, &dts_set)?;
  let (main, types) =
    extract_main_and_types(&config_file.json.exports, &dts_set);

  // Collect dependencies from all files. BTreeMap so the serialized
  // package.json keys come out in sorted order (reproducibility).
  let mut dependencies: BTreeMap<String, String> = BTreeMap::new();

  // Merge dependencies from all processed files
  for file in files {
    for (name, version) in &file.dependencies {
      dependencies.insert(name.clone(), version.clone());
    }
  }

View on GitHub (pinned to 9ad36f7a2c)