Discussion: Treating Changes in Dispatchable Function Errors as Breaking Changes

Discussion: Treating Changes in Dispatchable Function Errors as Breaking Changes

Hello everyone,

I recently came across a PR in the Polkadot SDK repository (#3286) that introduces a change to the error returned by the pallet assets’ mint dispatchable function in a specific case. While this might seem like a minor adjustment at first glance, I believe it constitutes a breaking change for smart contracts and other dependent applications that rely on this function’s behavior.

Why This Matters
Smart contracts and other integrations often depend not only on the successful execution of dispatchable functions but also on how errors are handled. A change in the error returned can impact contract logic, error handling mechanisms, and external systems that parse these responses. Any deviation from the expected error behavior could:

  1. Break Existing Contracts: Contracts relying on the previous error response may no longer function as intended.
  2. Impact Error Handling Logic: External applications, monitoring tools, and libraries might have implemented specific logic based on the prior error behavior.
  3. Create Deployment Risks: Developers upgrading to a newer SDK version might encounter unforeseen issues, leading to deployment failures or runtime errors.

My Concern
From reviewing the PR and associated discussions, it doesn’t seem like this change is being treated as a breaking change. I believe this underestimates the potential impact on users of the SDK.

I’d love to hear the community’s thoughts on this topic. Have others encountered issues arising from changes like this? Should the SDK team adopt a stricter policy regarding changes to errors in dispatchable functions?

Looking forward to your insights and feedback.

Best regards,

Daan | R0GUE

3 Likes

As context, actually altering enum Error of a pallet is part of the public interface, so the change will be processed as a major bump in the polkadot-sdk release system.

I’d love to hear the community’s thoughts on this topic. Have others encountered issues arising from changes like this? Should the SDK team adopt a stricter policy regarding changes to errors in dispatchable functions?

I agree that if the change is a nice-to-have and does not solve any major issue, it is likely more worthwhile to keep it as-is.

This is a problem that the Polkadot fellowship will also encounter in some way: As pallet_revive gets deployed on AH, it will likely rely on a part of the pallet APIs to be very stable, and breaking them needlessly will be an avoidable headache.

We are already at a point where we generally review PRs with a stricter policy around breaking changes in the Polkadot-SDK. And as noted above, we ensure any breaking change is actually a major bump, so at least you are not forced to deal with it. The degree to which we should be conservative is generally fuzzy.

I am not familiar with the context of this PR per-se, so I cannot say if it was avoidable or not. Tagging @Muharem to chime in more.

But that only helps code that directly links against said crate. i.e code that is part of the same runtime. Doesn’t help off chain tooling or contracts which will just break.

1 Like

Summary of the Issue in the PR

The change introduced in the PR modifies the error returned by the mint function in pallet_assets when the asset is in destroy mode (i.e., start_destroy has been called). Previously, the function returned the module error pallet_assets::Error::AssetNotLive, but now it returns DispatchError::Token(Token::UnknownAsset).

Why is this a problem

For downstream projects, e.g. contracts, applications or a chain consistency in error outputs is critical. Let’s take the example of a chain aiming to provide stable, versioned APIs to smart contracts—like Pop Network with the Pop API—that ensures contracts do not have to deal with breaking changes in runtime behavior. This change in error behavior makes it exceedingly difficult, if not impossible, to provide a stable API.

In attempting to map the AssetNotLive error from mint to TokenError::UnknownAsset for consistency, the following challenge arose:

  • Scenario 1: Minting an asset in destroy mode correctly maps AssetNotLive to TokenError::UnknownAsset.
  • Scenario 2: Minting an asset that does not exist also maps to TokenError::UnknownAsset, which introduces ambiguity.

There’s no reliable way to differentiate between these scenarios without querying state to determine whether the asset exists—an additional complexity that defeats the purpose of consistent error handling.

This inconsistency arises because the SDK does not define when a dispatchable function (or the pallet as a whole) should return specific errors like AssetNotLive or TokenError::UnknownAsset (another example I encountered some time ago). This lack of definition leaves downstream projects guessing, making stable error output nearly impossible to achieve.

Closing Thoughts

Polkadot’s strategy is to target applications, applications want stability, and this issue highlights a gap in the SDK that can hinder adoption. Other ecosystems set a precedent by offering defined and stable APIs with consistent error handling for their smart contracts and integrations. If Polkadot aims to be a go-to platform for developers building long-term solutions, ensuring consistent, defined error outputs for SDK pallets is a necessity.

We hope this explanation provides a clear overview of the issue and why we believe it is significant. This is a problem that we think needs solving, and we are eager to discuss it further with the community to explore potential paths forward.

Best regards,
Daan | R0GUE

3 Likes