@W-24017820@ fix(package-convert): actionable error when Dev Hub lacks 2GP - #931
Open
agayakwad-salesforce wants to merge 1 commit into
Open
agayakwad-salesforce wants to merge 1 commit into
agayakwad-salesforce wants to merge 1 commit into
Conversation
agayakwad-salesforce
force-pushed
the
t/2gp-readiness/w-24017820/actionable-error-for-convert-without-2gp
branch
from
September 11, 2026 23:10
d5ec8f1 to
fd58621
Compare
ravipanguluri
approved these changes
Sep 12, 2026
… 2GP When running sf package convert against a Dev Hub without second-generation managed packaging enabled, the Package2 tooling query in findOrCreatePackage2 threw a raw INVALID_TYPE "sObject type 'Package2' is not supported" error with no actionable guidance. Wrap the Package2 query and the Package2 create path so the "not supported" error is surfaced as a clear, actionable message (convertPackagingNotEnabledOnOrg), consistent with the existing handling in package version retrieve. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
agayakwad-salesforce
force-pushed
the
t/2gp-readiness/w-24017820/actionable-error-for-convert-without-2gp
branch
from
September 16, 2026 07:42
fd58621 to
45ee002
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
@W-24017820@ Actionable error when a Dev Hub lacks Second-Generation Packaging
TL;DR
When a user runs
sf package convertorsf package createagainst a Dev Hubthat does not have Second-Generation Managed Packages enabled, the CLI used to
fail with a raw, unexplained server error and zero guidance. This PR replaces those
cryptic errors with a clear, actionable message that names the real cause and tells the
user exactly what to do.
sf package convertINVALID_TYPE: sObject type 'Package2' is not supported. …Can't convert package. The Dev Hub you specified doesn't have the Second-Generation Managed Packages setting enabled. Enable this setting on your Dev Hub, and try again.sf package createNOT_FOUND: The requested resource does not existCan't create package. The Dev Hub you specified doesn't have the Second-Generation Managed Packages setting enabled. Enable this setting on your Dev Hub, and try again.1. The problem
The 2GP packaging commands assume the target Dev Hub has the Second-Generation
Managed Packages setting enabled. When it is not enabled, the
Package2entitydoes not exist on that org, and the very first server call in each command fails.
Because those first calls had no error handling for this condition, the raw
tooling-API error propagated straight to the user:
sf package convert→sf package create→Neither message mentions 2GP, the Dev Hub, or any next step. A user has no way to know
the real problem is simply "2GP isn't enabled on this Dev Hub."
2. Why it happens (root cause)
The two commands reach
Package2through two different tooling APIs, which is whythey fail with two different raw errors:
sf package convert— via a SOQL queryfindOrCreatePackage2(src/package/packageConvert.ts) runs:When
Package2is unknown, the SOQL parser rejects the query withINVALID_TYPE: sObject type 'Package2' is not supported.sf package create— via a REST sObject callcreatePackage(src/package/packageCreate.ts) runs:When
Package2is unknown, the tooling REST endpoint/sobjects/Package2does notexist, so it 404s with
NOT_FOUND: The requested resource does not exist.A subtle secondary bug in
package createpackageCreate.tsalready routed its.catchthroughapplyErrorAction/massageErrorMessageinpackageUtils.ts.applyErrorActiondoes have aNOT_FOUNDbranch — but it only appends an action (packageNotEnabledAction); itnever rewrites the headline message. Worse, that action is then silently dropped by
SfError.wrap(), whosefromBasicErrorhelper copies onlymessage,name, andcauseonto the newSfError— notactions. Net effect: the user saw the bareNOT_FOUNDwith no message improvement and no action hint (actions: None).3. How to reproduce the "before" behaviour
Prerequisites (local Core dev environment used for verification):
033…) for the convert path.sfdx-project.jsonwith a valid namespace.Reproduce
convert:Reproduce
create:Confirm the underlying condition directly:
4. What the fix changes
New user-facing messages
messages/package_version_create.md→convertPackagingNotEnabledOnOrgmessages/package_create.md→createPackagingNotEnabledOnOrgsrc/package/packageConvert.ts(convert path)Package2SOQL query infindOrCreatePackage2in atry/catch. If theerror is the "not supported" condition, throw
convertPackagingNotEnabledOnOrg;otherwise rethrow unchanged.
Package2create path — ifcreateResult.errorsreports the samecondition, throw the actionable message instead of the generic
combineSaveErrorsoutput.
isPackage2NotSupportedError(err)— matches the SOQL error on asubstring (
sObject type 'Package2' is not supported.) because the full servermessage may append custom-object WSDL boilerplate. Handles both
Errorinstances andjsforce
SaveErrorplain objects.src/package/packageCreate.ts(create path)package_createmessage bundle.createPackage, intercept before themassageErrorMessage/SfError.wrappipeline: if the error is the 2GP-not-enabled condition, throw
createPackagingNotEnabledOnOrg. Also guard thecreateResult.errorspath.isPackagingNotEnabledError(err)— for this path the signal is the REST404, so it matches
name === 'NOT_FOUND'and messageThe requested resource does not exist. It readserrorCode/statusCodefromjsforce
SaveErrorobjects as well asErrorinstances.package createnever issues a SOQL query, so that form cannot occur on this path.Tests
test/package/packageConvert.test.ts— cases asserting the actionable message on boththe query-throws and create-result paths, and that the raw
INVALID_TYPEtext does notleak.
test/package/packageCreate.test.ts— newcreatePackage 2GP-not-enabled handlingblock: (1)
NOT_FOUNDthrown by the create call, (2)NOT_FOUNDreported increateResult.errors, (3) unrelated errors rethrown unchanged.5. Testing done (after-behaviour validation)
Automated
Manual, end-to-end against a real no-2GP Dev Hub (local Core)
sf package convertConvertPackagingNotEnabledOnOrgError+ actionable messagesf package createCreatePackagingNotEnabledOnOrgError+ actionable messagesf package createNotADevHubError(flag-parse gate) — fix does not false-positivesf package convertNotADevHubErrorExact "after" output —
sf package createon a no-2GP Dev Hub:JSON:
name/code=CreatePackagingNotEnabledOnOrgError,exitCode=1.6. How a reviewer can test this fix
Packages on it) and authenticate the CLI to it.
lib:package createin an sfdx project directory:CreatePackagingNotEnabledOnOrgErrorwith the actionable message (notNOT_FOUND).package convertwith a 1GP033…package id:ConvertPackagingNotEnabledOnOrgErrorwith the actionable message (notINVALID_TYPE).confirm you still get
NotADevHubError(the fix must not mask that).7. Notes, scope, and follow-ups
1). This is purely a messaging improvement; automationkeying off exit status is unaffected.
actionsblock (consistentwith the existing
packageVersionRetrievehandling). If we prefer a formal "Try this:"action hint, that's a small follow-up.
sf package version createis intentionally out of scope. On a no-2GP Dev Hub itfails earlier with
ErrorNoIdInHubErrorbecause it requires a real0Hopackage idthat cannot exist without 2GP (chicken-and-egg). There is no faithful "real 0Ho +
no 2GP" state to handle, so it was left as-is.
SfError.wrap'sfromBasicErrordrops.actions, so any action added byapplyErrorActionin the create.catchpath iscurrently discarded. This fix sidesteps it; a dedicated change should address the
general case.