denoland/deno · error · AnyError
Failed to publish packages
Error message
Failed to publish {} packages: What it means
When `deno publish` publishes a workspace with multiple packages and more than one package fails, the individual errors are combined into a single error with this header followed by one bulleted entry per package (each rendered with its full context chain, e.g. 'Failed to publish @scope/name: <cause>'). It is purely an aggregation wrapper: the real causes are the per-package errors listed below the header.
Solutions
- Read each `* <error>` bullet under the header; every bullet is an independent per-package failure with its full cause chain — fix them individually.
- Fix the most mechanical errors first (missing 'version', missing 'exports', slow types), then re-run `deno publish --dry-run` to re-validate all members cheaply.
- If a package failed only because its version already exists on jsr.io, bump that package's version (or use --allow-dirty/--skip-verification as appropriate) instead of republishing.
- Re-run `deno publish` after fixes; packages that succeeded are reported separately, so only failed ones retry.
Defensive patterns
Strategy: try-catch
Validate before calling
const cmd = new Deno.Command('deno', { args: ['publish', '--dry-run'] });
const { success, stderr } = await cmd.output();
if (!success) {
// dry-run surfaces the same per-package errors before any upload
throw new Error(new TextDecoder().decode(stderr));
} Try / catch
try {
await runDeno(['publish']);
} catch (e) {
if (String(e.message).startsWith('Failed to publish')) {
// each bullet after the header is one independent package failure
const failures = e.message.split('\n\n* ').slice(1);
for (const f of failures) fixOrReport(f);
}
} Prevention
- Always run `deno publish --dry-run` first in CI; it catches the same per-package errors with no side effects.
- Fix shared scaffolding mistakes once across the workspace (version, exports, slow types).
- Expect already-published versions to fail and bump versions before the real publish run.
When it happens
Trigger: A workspace publish where 2+ members each failed for independent reasons — e.g. one missing a `version` field, another having slow types, a third hitting a registry auth/409 version-already-exists error.
Common situations: First publish of a monorepo where several members share the same scaffolding mistake (all missing version, all missing exports map); partial network failure during a multi-package upload; one package already published at that version while another has an unrelated error.
Related errors
- Cannot use --set-version when publishing a workspace…
- No packages to publish
- unable to find npm package in workspace
- Cannot represent compiler option
- Checksum mismatch for
AI-assisted analysis of denoland/deno@f7822238ca (2026-08-20).
Data as JSON: /api/errors/cc8a2307a736524c.
Report an issue: GitHub.
Appendix: source
Thrown at cli/tools/publish/mod.rs:1089
}
Err(combine_publish_errors(errors))
}
}
/// Combines the errors collected while publishing multiple packages into a
/// single error, preserving each error's context chain.
fn combine_publish_errors(mut errors: Vec<AnyError>) -> AnyError {
if errors.len() == 1 {
return errors.remove(0);
}
let mut message = format!("Failed to publish {} packages:", errors.len());
for err in &errors {
// `{:#}` renders the full anyhow context chain (e.g.
// "Failed to publish @scope/name: <cause>").
message.push_str(&format!("\n\n* {:#}", err));
}
deno_core::anyhow::anyhow!(message)
}
async fn publish_package(
http_client: &HttpClient,
package: Rc<PreparedPublishPackage>,
registry_api_url: &Url,
registry_url: &Url,
authorization: &str,
provenance: bool,
) -> Result<(), AnyError> {
log::info!(
"{} @{}/{}@{} ...",
colors::intense_blue("Publishing"),
package.scope,
package.package,
package.version
);
View on GitHub (pinned to f7822238ca)