Repository navigation
Quote strings a stricter YAML parser would read as a number - #146
Merged
Merged
Conversation
PyYAML omits quotes when its own resolver reads the bare scalar back as a string, which is a weaker guarantee than a Kubernetes manifest needs. An AWS account id with a leading zero is the case that bites: 032445865269 is not valid octal because of the 8 and the 9, and the decimal pattern rejects the leading zero, so PyYAML calls it a string and writes it bare. go-yaml, which the API server parses with, falls through to its float parser, which accepts the leading zero, and the field is rejected with "json: cannot unmarshal number into Go value of type string". Eleven roles and a provision token in portswigger-cloud/system failed to apply this way, and quoting them at source did not help: the value reaches the dumper as a str either way, so the quoting is decided here and nowhere else.
This was referenced Sep 11, 2026
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.
_literal_str_representerleaves a single-line string bare, inheriting PyYAML's rule of quoting only when its own resolver would read the bare form back as something other than a string. That guarantees a PyYAML round-trip, but the consumer is the Kubernetes API server, which parses with go-yaml — and the two resolvers disagree.They disagree on exactly the values that broke:
yq)032445865269!!floatstr016624044925!!floatstr031692804905!!floatstr132827254700!!intint— already quoted0123!!intint— already quotedAn AWS account id with a leading zero stops being valid octal once it contains an 8 or a 9, and PyYAML's decimal pattern rejects a leading zero — so PyYAML resolves it to a string and writes it bare. go-yaml tries octal, fails, and falls through to its float parser, which is happy with the leading zero. The API server then rejects it against a string-typed field:
Eleven Teleport roles and
TeleportProvisionToken/iam-node-joininportswigger-cloud/systemfailed to apply this way. Quoting at source does not help — the value reaches the dumper as astrhowever it was written, so quoting is decided here and nowhere else.The representer now quotes any string whose bare form could be read as a number. Verified with
yq(go-yaml): quoted values come back!!str, and real integers are untouched at!!int.Expected output change: values PyYAML already quoted are unaffected, so the diff should be limited to leading-zero numeric strings. Worth a generation run before release — any other diff is a second instance of this bug rather than a regression.
Possible follow-up: a round-trip check that reparses emitted YAML with go-yaml and asserts every
strsurvives as a string, which would catch the rest of this class instead of only the case we hit.