Skip to content

fix: permit empty string for ErrPrefix#2392

Open
humanborch wants to merge 3 commits intospf13:mainfrom
humanborch:fix/issue-2226
Open

fix: permit empty string for ErrPrefix#2392
humanborch wants to merge 3 commits intospf13:mainfrom
humanborch:fix/issue-2226

Conversation

@humanborch
Copy link
Copy Markdown

Currently, when a developer sets cmd.SetErrPrefix(""), the system incorrectly assumes the prefix was left unset due to "" being the default zero-value for a string, and falls back to prepending "Error: " and a trailing space. This makes it impossible to output pure JSON errors because of the leading space injected by c.PrintErrln.

This PR introduces an unexported errPrefixSet boolean to cleanly demarcate when the user has explicitly SetErrPrefix.

  • Modified ErrPrefix() getter to honor the marker without breaking the public Command struct API.
  • Added a conditional downstream print block inside ExecuteC to prevent fmt.Sprintln from injecting a leading space when the prefix evaluates to empty.
  • Added TestRootErrPrefixEmpty to command_test.go to explicitly prevent regressions.
  • Existing unit tests pass.

Fixes #2226

Currently, when a developer sets `cmd.SetErrPrefix("")`, the system incorrectly assumes the prefix was left unset due to `""` being the default zero-value for a string, and falls back to prepending `"Error: "` and a trailing space. This makes it impossible to output pure JSON errors because of the leading space injected by `c.PrintErrln`.

This PR introduces an unexported `errPrefixSet` boolean to cleanly demarcate when the user has explicitly `SetErrPrefix`.

* Modified `ErrPrefix()` getter to honor the marker without breaking the public `Command` struct API.
* Added a conditional downstream print block inside `ExecuteC` to prevent `fmt.Sprintln` from injecting a leading space when the prefix evaluates to empty.
* Added `TestRootErrPrefixEmpty` to `command_test.go` to explicitly prevent regressions.
* Existing unit tests pass.

Fixes spf13#2226
@CLAassistant
Copy link
Copy Markdown

CLAassistant commented Apr 17, 2026

CLA assistant check
All committers have signed the CLA.

@marckhouzam
Copy link
Copy Markdown
Collaborator

Do we need a way to unset the error prefix now that using “” won’t unset?

@marckhouzam
Copy link
Copy Markdown
Collaborator

marckhouzam commented Apr 18, 2026

This makes sense to me but I believe this has backwards-compatibility implications. Existing programs might be using ”” to unset the error prefix but this PR would change how that behaves.

It wouldn’t be pretty but we could have a function SetErrorPrefixEmpty() instead. And I’m sure there are other ways also.

@humanborch
Copy link
Copy Markdown
Author

Good catch on the backwards-compatibility issue! You're totally right that existing programs might be relying on SetErrPrefix(""') to unset the prefix back to the default.

I've pushed an update that reverts SetErrPrefix(""') back to its original behavior so we don't break anything. Following your suggestion, I added a new SetErrPrefixEmpty(bool) method instead. This gives developers a clean, explicit way to suppress the prefix without overloading the meaning of an empty string. I also added a test to ensure that SetErrPrefix(""') successfully restores the default prefix.

Let me know what you think of this approach!

Copy link
Copy Markdown
Collaborator

@marckhouzam marckhouzam left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this

Comment thread command.go
@@ -377,6 +379,12 @@
c.errPrefix = s
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this function is called with an argument "" it should unset the error prefix which should cause ErrPrefix() to check if the parent has an error prefix.

This won't happen if SetErrPrefixEmpty(true) has been called before.
I think we also need to call c.errPrefixEmpty = false in this function to truly unset the error prefix

Comment thread command.go
// SetErrPrefixEmpty sets whether the error message prefix should be empty.
// If set to true, this suppresses the default "Error: " prefix.
func (c *Command) SetErrPrefixEmpty(empty bool) {
c.errPrefixEmpty = empty
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same idea that if SetErrPrefix("hello") was called before, this function should undo that, or else the error prefix will not actually show as empty.

So we should set c.errPrefix = "" here I think

Comment thread command.go
c.versionTemplate = tmpl(s)
}

// SetErrPrefix sets error message prefix to be used. Application can use it to set custom prefix.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a comment saying that "to unset the error prefix, this function should be called with the empty string. To prevent an error prefix from being used, the function SetErrPrefixEmpty(true) should be used"

Comment thread command.go
}

// SetErrPrefixEmpty sets whether the error message prefix should be empty.
// If set to true, this suppresses the default "Error: " prefix.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please a comment along the lines of to unset the error prefix (so the parent chain can be checked), please use SetErrPrefix("")

@humanborch
Copy link
Copy Markdown
Author

@marckhouzam Thanks for the great review! I really appreciate the time you've taken to look into this and provide such helpful feedback.

I've just pushed a commit that addresses your points:

  • SetErrPrefix now explicitly unsets errPrefixEmpty (c.errPrefixEmpty = false).
  • SetErrPrefixEmpty(true) now explicitly clears the prefix string (c.errPrefix = "").
  • Added the requested comments to both functions so the behavior is clear.

I'm thrilled to be able to contribute back to a project I use every day. Let me know if there's anything else needed!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

permit empty string for ErrPrefix

3 participants