denoland/deno · error

No packages to publish

Error message

No packages to publish

What it means

After building the module graph and preparing tarballs, publish asserts that at least one package survived: `prepared_data.package_by_name` must not be empty. This bail fires when the resolved publish set was empty at preparation time — typically every candidate member was excluded from publishing. Note the separate, earlier path: when every package is filtered out as already published, publish instead prints 'Success - All packages are already published' and exits 0, so this error means nothing was ever eligible.

Source

Thrown at cli/tools/publish/mod.rs:189

    ),
    cli_factory.module_graph_creator().await?.clone(),
    cli_factory.type_checker().await?.clone(),
    cli_options.clone(),
    module_content_provider,
  );

  let prepared_data = publish_preparer
    .prepare_packages_for_publishing(
      publish_flags.allow_slow_types,
      &diagnostics_collector,
      publish_configs,
    )
    .await?;

  diagnostics_collector.print_and_error()?;

  if prepared_data.package_by_name.is_empty() {
    bail!("No packages to publish");
  }

  if std::env::var("DENO_TESTING_DISABLE_GIT_CHECK")
    .ok()
    .is_none()
    && !publish_flags.allow_dirty
    && let Some(dirty_text) =
      check_if_git_repo_dirty(cli_options.initial_cwd()).await
  {
    log::error!("\nUncommitted changes:\n\n{}\n", dirty_text);
    bail!(
      "Aborting due to uncommitted changes. Check in source code or run with --allow-dirty"
    );
  }

  if publish_flags.dry_run {
    for (_, package) in prepared_data.package_by_name {
      log::info!(

View on GitHub (pinned to f7822238ca)

Solutions

  1. Re-enable publishing for the member you want: remove `"publish": false` from its deno.json.
  2. Ensure at least one config has `name`, `version`, and `exports` so it registers as a JSR package.
  3. If everything is intentionally private, don't run `deno publish` — use `deno pack` or a private registry workflow instead.

Example fix

// deno.json (before — nothing publishable)
{
  "workspace": ["./packages/a", "./packages/b"],
  "publish": false
}
// packages/a/deno.json (after — member opt-in)
{
  "name": "@scope/a",
  "version": "1.0.0",
  "exports": "./mod.ts"
}
Defensive patterns

Strategy: validation

Validate before calling

# fail fast if no workspace config is publishable (name + exports + not publish:false)
node -e '
const fs = require("fs");
const read = (p) => JSON.parse(fs.readFileSync(p, "utf8"));
const root = read("deno.json");
const members = (root.workspace ?? []).map((m) => read(`${m}/deno.json`));
const publishable = [root, ...members].some((c) => c.name && c.exports && c.publish !== false);
if (!publishable) { console.error("no publishable packages — nothing to publish"); process.exit(1); }'

Prevention

When it happens

Trigger: `deno publish` where no package registers for the publish set: a workspace whose members are all excluded via `"publish": false` (and the root config falls through the name/publish/exports checks without bailing), or configs that never become JSR packages (missing name+exports).

Common situations: Monorepos that mark members `"publish": false` for private packages and later exclude the last publishable member; scaffolding a new package whose deno.json lacks `exports`; running publish after restructuring a workspace.

Related errors


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