Having difficulty in understanding one of the questions of FAQ #30

Closed
opened 2026-02-17 11:03:50 -06:00 by GiteaMirror · 5 comments
Owner

Originally created by @ghost on GitHub (Jul 21, 2012).

Hi

Please see this question:

What should I do if the bug that is being fixed returns the code to being compliant with the public API (i.e. the code was incorrectly out of sync with the public API documentation)?

Use your best judgment. If you have a huge audience that will be drastically impacted by changing the behavior back to what the public API intended, then it may be best to perform a major version release, even though the fix could strictly be considered a patch release. Remember, Semantic Versioning is all about conveying meaning by how the version number changes. If these changes are important to your users, use the version number to inform them.

I have difficulty in understanding it. "What should I do if the bug that is being fixed", till here, we talk about the bug, right? "returns the code", what does it mean? Can fixing a bug possibly return "code"? "being compliant with the public API", what's the problem then? I fixed a bug, and now everything is fine, and compliant with the public API. Why should I even up-version? I mean, I understand this as a refactor, more than a change of public signatures of the API.

Thanks.

Originally created by @ghost on GitHub (Jul 21, 2012). Hi Please see this question: > What should I do if the bug that is being fixed returns the code to being compliant with the public API (i.e. the code was incorrectly out of sync with the public API documentation)? > > Use your best judgment. If you have a huge audience that will be drastically impacted by changing the behavior back to what the public API intended, then it may be best to perform a major version release, even though the fix could strictly be considered a patch release. Remember, Semantic Versioning is all about conveying meaning by how the version number changes. If these changes are important to your users, use the version number to inform them. I have difficulty in understanding it. "What should I do if the bug that is being fixed", till here, we talk about the bug, right? "returns the code", what does it mean? Can fixing a bug possibly return "code"? "being compliant with the public API", what's the problem then? I fixed a bug, and now everything is fine, and compliant with the public API. Why should I even up-version? I mean, I understand this as a refactor, more than a change of public signatures of the API. Thanks.
Author
Owner

@plabanauskis commented on GitHub (Jul 30, 2012):

I believe this question should be rephrased because I had some hard time understanding it also.

I will try to explain. Let's say you have introduced a bug fix in your new patch version 1.0.1. Then you notice that this bug fix does not comply with the public API (maybe method that should return 0 or 1 now returns 0, 1 or -1 as a result of the bug fix). You then fix this, hence the code with the new fix is compliant with the public API again (i.e. returns to being compliant).
Then you should decide what version this fix is going to have. If the user base using the "bad" 1.0.1 is large, then you may find it better to release a new major version 2.0.0 INSTEAD OF 1.0.2. Otherwise you may just go with the 1.0.2 and hope that nobody would even notice this incompatibility.

@plabanauskis commented on GitHub (Jul 30, 2012): I believe this question should be rephrased because I had some hard time understanding it also. I will try to explain. Let's say you have introduced a bug fix in your new patch version 1.0.1. Then you notice that this bug fix does not comply with the public API (maybe method that should return 0 or 1 now returns 0, 1 or -1 as a result of the bug fix). You then fix this, hence the code with the new fix is compliant with the public API again (i.e. returns to being compliant). Then you should decide what version this fix is going to have. If the user base using the "bad" 1.0.1 is large, then you may find it better to release a new major version 2.0.0 INSTEAD OF 1.0.2. Otherwise you may just go with the 1.0.2 and hope that nobody would even notice this incompatibility.
Author
Owner

@ghost commented on GitHub (Jul 31, 2012):

Dear pauliuslab,
Thanks for replying

I still don't get the overall meaning. Let's say that I have the GetUserStatus(int userId) method, which returns either 0 (meaning offline) or 1 (meaning online). The version is now 1.0.1 and in the public API documentation everything is fine.

Now someone online reports that his status is shown as offline, thus there should be a bug in fetching user status from DB or updating user status or somewhere else. But the bug is "an online guy's status is shown as offline".

Thus we try to track the issue and we find out that we should add another state called "inactive" which means that the user is online, but hasn't been working with our system for say 20 minutes.

Now that we've fixed the bug, the method returns 3 states, while in the public API documentation it says that it returns 2 values.

If I change the version from 1.0.1 to 1.0.2 and also update the public API, then what's wrong here? I honestly don't get it.

@ghost commented on GitHub (Jul 31, 2012): Dear pauliuslab, Thanks for replying I still don't get the overall meaning. Let's say that I have the GetUserStatus(int userId) method, which returns either 0 (meaning offline) or 1 (meaning online). The version is now 1.0.1 and in the public API documentation everything is fine. Now someone online reports that his status is shown as offline, thus there should be a bug in fetching user status from DB or updating user status or somewhere else. But the bug is "an online guy's status is shown as offline". Thus we try to track the issue and we find out that we should add another state called "inactive" which means that the user is online, but hasn't been working with our system for say 20 minutes. Now that we've fixed the bug, the method returns 3 states, while in the public API documentation it says that it returns 2 values. If I change the version from 1.0.1 to 1.0.2 and also update the public API, then what's wrong here? I honestly don't get it.
Author
Owner

@robsimmons commented on GitHub (Jul 31, 2012):

I may be badly misunderstanding the question: if you modify your code so that it treats "inactive" as "online", that's reasonably a bug fix, a patch release - bump to 1.0.2, and the method returns two values but it returns a better value in one of the corner cases. But you can't change the public API and have that be a patch-level change!

Say that I'm using your code, and my code is written to the API such that, if it gets one of the two values document in the API, it does something innocuous and if it gets some unknown value then it does something arbitrarily bad. If you update from 1.0.1 to 1.X.Y, one of the big features of semantic versioning is that, because my code is written to your 1.0.1 API, I get to trust that it will still work just fine with any greater 1.X.Y release without rereading the API - that's the promise you're making by using semantic versioning.

You could extend your API with an extra BetterGetUserStatus(int userId) method that returns three values - that's a minor revision, so you'd go to 1.1.0. You then simultaneously deprecate GetUserStatus(int userId), but you can't remove it until you make a major version bump. Or you could just bump to 2.0.0 and change the behavior of GetUserStatus(int userId). Either of those will work fine from my perspective, a user of 1.0.1 GetUserStatus(int userId). What you proposed will not work, and will make my code do something arbitrarily bad.

@robsimmons commented on GitHub (Jul 31, 2012): I may be badly misunderstanding the question: if you modify your code so that it treats "inactive" as "online", that's reasonably a bug fix, a patch release - bump to 1.0.2, and the method returns two values but it returns a better value in one of the corner cases. But you can't change the public API and have that be a patch-level change! Say that I'm using your code, and my code is written to the API such that, if it gets one of the two values document in the API, it does something innocuous and if it gets some unknown value then it does something arbitrarily bad. If you update from 1.0.1 to 1.X.Y, one of the big features of semantic versioning is that, because my code is written to your 1.0.1 API, I get to trust that it will still work just fine with any greater 1.X.Y release without rereading the API - that's the promise you're making by using semantic versioning. You could _extend_ your API with an extra BetterGetUserStatus(int userId) method that returns three values - that's a minor revision, so you'd go to 1.1.0. You then simultaneously deprecate GetUserStatus(int userId), but you can't remove it until you make a major version bump. Or you could just bump to 2.0.0 and change the behavior of GetUserStatus(int userId). Either of those will work fine from my perspective, a user of 1.0.1 GetUserStatus(int userId). What you proposed will _not_ work, and will make my code do something arbitrarily bad.
Author
Owner

@haacked commented on GitHub (Mar 13, 2013):

Yeah, I think the timeline this question addresses is simple:

  • 1.0.0 - initial public release
  • 1.0.1 - Intended to patch 1.0.0 but accidentally contains a breaking change. In an alternate universe where this change was intended, it would be 2.0.0. But in this universe, it was an accident and is 1.0.1.
  • 1.0.2 - Fixes the breaking change. Thus if 1.0.1 never had the breaking change, this would rightfully also be a patch of 1.0.0

I think the question is here because strictly speaking, 1.0.2 is a breaking change from 1.0.1 and thus should increment the MAJOR version per SemVer rules.

However, 1.0.1 being a breaking change wasn't intentional. So if one of the following is true:

  • You have a small user base.
  • Your user base is forgiving of breaking changes.
  • You caught the issue quickly.

You could use your good judgment to simply release the fix as 1.0.2 instead of 2.0.0. After all, once 1.0.2 in published, most package managers won't upgrade someone from 1.0.0 to 1.0.1. They'll go straight to 1.0.2 which is really what you intended all along.

In any case, would you mind submitting a PR with improved wording for the question? I agree that the wording is a little confusing. :)

@haacked commented on GitHub (Mar 13, 2013): Yeah, I think the timeline this question addresses is simple: - `1.0.0` - initial public release - `1.0.1` - _Intended_ to patch `1.0.0` but accidentally contains a breaking change. In an alternate universe where this change _was_ intended, it would be `2.0.0`. But in this universe, it was an accident and is `1.0.1`. - `1.0.2` - Fixes the breaking change. Thus if `1.0.1` never had the breaking change, this would rightfully also be a patch of `1.0.0` I think the question is here because strictly speaking, `1.0.2` is a breaking change from `1.0.1` and thus should increment the `MAJOR` version per SemVer rules. However, `1.0.1` being a breaking change wasn't intentional. So if one of the following is true: - You have a small user base. - Your user base is forgiving of breaking changes. - You caught the issue quickly. You could use your good judgment to simply release the fix as `1.0.2` instead of `2.0.0`. After all, once `1.0.2` in published, most package managers won't upgrade someone from `1.0.0` to `1.0.1`. They'll go straight to `1.0.2` which is really what you intended all along. In any case, would you mind submitting a PR with improved wording for the question? I agree that the wording is a little confusing. :)
Author
Owner

@Wardrop commented on GitHub (Mar 23, 2013):

Semantic versioning depends on comprehensive documentation of your public API. If you release a patch-level change that accidentally changes the behaviour of the public API, but not the public API as it's documented, then the fix in my opinion should be applied as another patch, not a major release. Point being, users should be using your public API as documented. If they deviate from that, the onus is on them.

Of course, a lot public API's are auto-documented from the code, so then it goes back to your judgement as the developer. User base, time since bug was introduced, etc, all need to be considered. I'd say in the majority of cases, such a change would be considered patch-level, however in those rarer cases where the code hasn't behaved as defined by the public API for quite some time, and the behaviour of which is depended on, obviously changing it would constitute a major release.

@Wardrop commented on GitHub (Mar 23, 2013): Semantic versioning depends on comprehensive documentation of your public API. If you release a patch-level change that accidentally changes the behaviour of the public API, but not the public API as it's documented, then the fix in my opinion should be applied as another patch, not a major release. Point being, users should be using your public API as documented. If they deviate from that, the onus is on them. Of course, a lot public API's are auto-documented from the code, so then it goes back to your judgement as the developer. User base, time since bug was introduced, etc, all need to be considered. I'd say in the majority of cases, such a change would be considered patch-level, however in those rarer cases where the code hasn't behaved as defined by the public API for quite some time, and the behaviour of which is depended on, obviously changing it would constitute a major release.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/semver#30