News for hackers. Stuff that matters.
Re:I accidentally used YAML.parse instead of JSON.parse and ... by remram on Sunday January 23, 2022 @08:42PM (#30052685)
For example, this valid JSON doesn't parse as YAML:

    {
        "list": [
            {},
                {}
        ]
    }
(tested on Python)

edit: whitespace didn't quite make it through HN, here:

    json.loads('{\n  "list": [\n    {},\n\t{}\n    ]\n}')
    yaml.load ('{\n  "list": [\n    {},\n\t{}\n    ]\n}')
Re:I accidentally used YAML.parse instead of JSON.parse and ... by 0xbadcafebee on Sunday January 23, 2022 @08:58PM (#30052787)
Python's .netrc library also hasn't supported comments correctly for like 5 years. The bug was reported, it was never fixed. If I want to use my .netrc file with Python programs, I have to remove all comments (that work with every other .netrc-using program).

It's 2022 and we can't even get a plaintext configuration format from 1980 right.

Re:I accidentally used YAML.parse instead of JSON.parse and ... by macintux on Sunday January 23, 2022 @09:10PM (#30052861)
> It's 2022 and we can't even get a plaintext configuration format from 1980 right.

To me, it's more depressing that we've been at this for 50-60 years and still seemingly don't have an unambiguously good plaintext configuration format at all.

Re:I accidentally used YAML.parse instead of JSON.parse and ... by 0xbadcafebee on Sunday January 23, 2022 @10:32PM (#30053419)
I've been a Professional Config File Wrangler for two decades, and I can tell you that it's always nicer to have a config file that's built to task rather than being forced to tie yourself into knots when somebody didn't want to write a parser.

The difference between a data format and a configuration file is the use case. JSON and YAML were invented to serialize data. They only make sense if they're only ever written programmatically and expressing very specific data, as they're full of features specific to loading and transforming data types, and aren't designed to make it easy for humans to express application-specific logic. Editing them by hand is like walking a gauntlet blindfolded, and then there's the implementation differences due to all the subtle complexity.

Apache, Nginx, X11, RPM, SSHD, Terraform, and other programs have configuration files designed by humans for humans. They make it easy to accomplish tasks specific to those programs. You wouldn't use an INI file to configure Apache, and you wouldn't use an Apache config to build an RPM package. Terraform may need a ton of custom logic and functions, but X11 doesn't (Terraform actually has 2 configuration formats and a data serialization format, and Packer HCL is different than Terraform HCL). Config formats minimize footguns by being intuitive, matching application use case, and avoiding problematic syntax (if designed well). And you'd never use any of them to serialize data. Their design makes the programs more or less complex; they can avoid complexity by supporting totally random syntax for one weird edge case. Design decisions are just as important in keeping complexity down as in keeping good UX.

Somebody could take an inventory of every configuration format in existence, matrix their properties, come up with a couple categories of config files, and then plop down 3 or 4 standards. My guess is there's multiple levels of configuration complexity (INI -> "Unixy" (sudoers, logrotate) -> Apache -> HCL) depending on the app's uses. But that's a lot of work, and I'm not volunteering...

Re:I accidentally used YAML.parse instead of JSON.parse and ... by BiteCode_dev on Monday January 24, 2022 @07:06AM (#30056616)
I quite like CUELang (https://cuelang.org/), although it not yet widely supported.

It has a good balance between expressivity and readability, it got enough logic to be useful, but not so much it begs for abuses, it can import/export to yaml and json and features an elegant type system which lets you define both the schema and the data itself.

I hope it gains traction.

Re:I accidentally used YAML.parse instead of JSON.parse and ... by chillfox on Sunday January 23, 2022 @09:20PM (#30052933)
toml is pretty much the best one I have seen so far. At least for small to medium size config files.
Re:I accidentally used YAML.parse instead of JSON.parse and ... by dnautics on Sunday January 23, 2022 @09:24PM (#30052964)
Toml has some hairy bits. Lists of objects, lists of lists of objects, objects of lists of objects. Complex objects with top level fields...
Re:I accidentally used YAML.parse instead of JSON.parse and ... by chillfox on Sunday January 23, 2022 @09:35PM (#30053043)
Yep,

Although I do feel like there is a case to be made that if you need a Turing complete configuration language then in most cases you failed your users by pushing too many decisions on to them instead of deciding on sensible defaults.

And if you are dealing with one of the rare cases where Turing complete configuration is desirable then maybe use Lua or something like that instead.

Re:I accidentally used YAML.parse instead of JSON.parse and ... by dnautics on Sunday January 23, 2022 @09:40PM (#30053084)
I'm not defending YAML. YAML is terrible. It's even worse with logic and/or templates (looking at you, Ansible). Toml is certainly better but I'm still baffled as to why we don't have a "better YAML". YAML could almost be okay.
Re:I accidentally used YAML.parse instead of JSON.parse and ... by nerdponx on Sunday January 23, 2022 @10:14PM (#30053310)
There's also Lua, which is a full Turing complete language but is still pretty nice for writing config files, and is easy to embed.
Re:I accidentally used YAML.parse instead of JSON.parse and ... by nerdponx on Monday January 24, 2022 @10:51AM (#30059129)
Followup to my own post: don't forget about Scheme! Same nice properties as Lua, but you get some extra conveniences from using s-expressions (which can represent objects somewhat more flexibly, like XML, than Lua, which is more or less 1:1 with JSON).
Re:I accidentally used YAML.parse instead of JSON.parse and ... by brigandish on Monday January 24, 2022 @03:41AM (#30054932)
There's StrictYAML[1][2]. Can't say I've used it as let's face it, most projects bind themselves to a config language - whether that be YAML, JSON, HCL or whatever - but I'd like to.

[1] https://hitchdev.com/strictyaml/

[2] https://github.com/crdoconnor/strictyaml

Re:I accidentally used YAML.parse instead of JSON.parse and ... by chillfox on Sunday January 23, 2022 @09:46PM (#30053122)
Yeah, I think it's because nobody sat down and methodically created it.

People create config languages that work for their use case and then it is just a happy accident if it works for other things.

I don't think anyone has put serous effort into designing a configuration language. And by that I mean collect use cases, study how other config languages does things, make drafts, and test them. etc...

Re:I accidentally used YAML.parse instead of JSON.parse and ... by Too on Monday January 24, 2022 @12:40AM (#30054077)
Terraforms HCL is well designed.

I know a lot of people hate it but I find it to be the only configuration language that makes any sense for moderately large configs.

It’s short, readable, unambiguous, great IDE support. Got built in logic, variables, templates, functions and references to other resources - without being Turing complete imperative language, and without becoming a xml monstrosity.

Seriously there is nothing even close to it. Tell me one reasonable alternative in wide use that’s not just some preprocessor bolted onto yaml, like Helm charts or Ansible jinja templates.

Re:I accidentally used YAML.parse instead of JSON.parse and ... by randomswede on Tuesday January 25, 2022 @03:26AM (#30069546)
There's a world of difference between "simple configuration needs" and "complex configuration needs".

I will take a kubernetes deployment manifest as an example that you would want to express in a hypothetically perfect configuration language. Now, eventueally, you end up in the "containers" bit of the pod template inside the deployment spec.

And in that, you can (and arguably should) set resources. But, in an ideal world, when you set a CPU request (or, possibly, limit, but I will go with request for now) for an image that has a Go binary in it, you probably also want to have a "GOMAXPROCS" environment variable added that is the ceiling of your CPU allocation. And if you add a memory limit, and the image has a Java binary in it, you probably want to add a few of the Java memory-tuning flags.

And it is actually REALLY important that you don't repeat yourself here. In the small, it's fine, but if you end up in a position where you need to provide more, or less, RAM or CPU, on short notice (because after all, configuration files drive what you have in production, and mutating configuration is how you solve problems at speed, when you have an outage), any "you have to carefully put the identical thing in multiple places" is exactly how you end up with shit not fixing themselves.

So, yeah, as much hate as it gets, BCL may genuinely be better than every other configuration language I have had the misfortune to work with. And one of the things I looked forward to, when I left the G, was to never ever in my life have to see or think about BCL ever again. And then I saw what the world at large are content with. It is bloody depressing is what it is.

Re:I accidentally used YAML.parse instead of JSON.parse and ... by mirekrusin on Monday January 24, 2022 @06:02AM (#30056022)
Cuelang?
Re:I accidentally used YAML.parse instead of JSON.parse and ... by dnautics on Sunday January 23, 2022 @10:30PM (#30053406)
Yeah absolutely. I think there are four corners to the square: "meant to be written by humans/meant to be written by computers" and "meant to be read by humans/not meant to be read by humans". JSON is the king of meant to be written by computers read by humans, grpc and swift and protobuf and arrow can duke it out the written by computer/not read corner. We are missing good options in written by humans half.
Re:I accidentally used YAML.parse instead of JSON.parse and ... by svieira on Sunday January 23, 2022 @10:01PM (#30053220)
Dhall and Cue come to mind as ones that _feel_ more designed

https://github.com/dhall-lang/dhall-lang

https://cuelang.org/docs/usecases/configuration/

Re:I accidentally used YAML.parse instead of JSON.parse and ... by chillfox on Sunday January 23, 2022 @10:22PM (#30053365)
Interesting...

Me, the programmer finds those kinda cool.

And the sysadmin in me developed a dislike of both within 1 minute of looking at them.

Honestly, I think a good configuration library should be more than a spec, it should come with a library that handles parsing/validation. See, there are two sides to configuration, the user and the program. Knowledge about the values, defaults and types should live on the program side and should be documented. Then the user side of configuration can be clean and easy to read/write and most important of all, allow the user to accomplish the most common configuration without having to learn a new config language on top of learning the application.

Re:I accidentally used YAML.parse instead of JSON.parse and ... by BiteCode_dev on Monday January 24, 2022 @07:13AM (#30056688)
> Honestly, I think a good configuration library should be more than a spec, it should come with a library that handles parsing/validation

You just described CUELang.

The type system allows to define a schema as well as the data, in the same file, or in 2 separate ones. Then you can call either a cli tool (that works on linux, windows or mac) or use the Go lib (or bind to it).

For compat, cue can import and export to yaml, json and protobuf, as well as validate them.

Re:I accidentally used YAML.parse instead of JSON.parse and ... by stavros on Wednesday January 26, 2022 @04:32AM (#30083485)
Isn't Dhall basically the same (=have the same set of features)?
Re:I accidentally used YAML.parse instead of JSON.parse and ... by BiteCode_dev on Wednesday January 26, 2022 @10:04AM (#30086312)
In the same way python and js are basically the same.
Re:I accidentally used YAML.parse instead of JSON.parse and ... by stavros on Wednesday January 26, 2022 @12:02PM (#30088101)
Exactly. So if I'm going to learn/use one of them, there's no clear winner, really. Both also seem to also have about the same amount of adoption (zero?).
Re:I accidentally used YAML.parse instead of JSON.parse and ... by chillfox on Monday January 24, 2022 @09:32AM (#30058024)
Ok, you have convinced me to give it a serious look.
Re:I accidentally used YAML.parse instead of JSON.parse and ... by Ygg2 on Monday January 24, 2022 @03:34AM (#30054885)
> Yeah, I think it's because nobody sat down and methodically created it.

I think it's the opposite. There isn't a single config file that suits all needs.

Especially when you realize config isn't a single thing.

http://mikehadlow.blogspot.com/2012/05/configuration-complex...

Re:I accidentally used YAML.parse instead of JSON.parse and ... by chillfox on Monday January 24, 2022 @09:30AM (#30057981)
I guess that could also be the case.

I haven’t studied it, I am just generally feeling unhappy about most software configuration.

Re:I accidentally used YAML.parse instead of JSON.parse and ... by chillfox on Sunday January 23, 2022 @10:35PM (#30053433)
About Ansible, I think it gained it's success partially due to YAML.

Ansible is worse than Puppet and CFEngine in many ways, but it is superior in the user interface.

It managed to not only be a config management solution, but provide a universal config language that most apps could be configured with. So for a lot of use cases, if you know Anisible/YAML then you don't have to learn a new configuration language on top of learning a new application.

Re:I accidentally used YAML.parse instead of JSON.parse and ... by dnautics on Monday January 24, 2022 @12:46AM (#30054107)
The problem with Ansible is it's not universal, because most app playbooks, are configured in the worst possible way. In my experience typically you get handed an Ansible script, something which you'd hoped was declarative but isn't (like a version that apt-get grabs isn't fixed, or even, gets patched) then suddenly a downstream templated command fucks up, and the person who wrote the script isn't around anymore (or you don't trust their chops because they are a blowhard that worked at Google/Facebook and had a coddling ops team behind them in the past) or worse it's from "community" and has a billion hidden settings that you can't be bothered to grok - and so you have to dig so many layers down that you are better off just fucking rewriting the Ansible script to do the one thing which probably should have been four lines.

In any case, I found Ansible scripts to have like a 3 month half life. If we were lucky. I'm not bitter.

Re:I accidentally used YAML.parse instead of JSON.parse and ... by chillfox on Monday January 24, 2022 @03:03AM (#30054715)
haha, I can go on lengthy rants about every single configuration management system that I have used.

My dream configuration system should revert to default when the config is removed (keeping data). Have a simple/easy user interface. Have maintained modules with sane defaults for the 500 most common server software. I would rather there be no module than an abandoned one with unsafe defaults, that way it is clear that I would have to maintain my own if I want to use that particular piece of software. Performant, it really shouldn't take more than a few minutes to apply a config change. No more than 30 min for initial run.

Re:I accidentally used YAML.parse instead of JSON.parse and ... by Steltek on Monday January 24, 2022 @09:04AM (#30057645)
Early on, Ansible was primarily agent-less from the start which made it ridiculously easy to sneak into existing infrastructure and manual workflows. I probably would not have been able to stand up Puppet or Salt or whatever but I could run Ansible all by myself with no one to stop me :).
Re:I accidentally used YAML.parse instead of JSON.parse and ... by vitiral on Monday January 24, 2022 @08:35AM (#30057382)
I'm curious what your thoughts are on a config language I'm working on.

GitHub.com/vitiral/zoa

It has both binary and textual representation (with the first byte being able to distinguish them), and the syntax is clean enough I'm planning on extending it into a markup language as well.

Re:I accidentally used YAML.parse instead of JSON.parse and ... by pc86 on Sunday January 23, 2022 @09:38PM (#30053071)
Even if you have sensible defaults don't you still need to be able to parse configured changes?
Re:I accidentally used YAML.parse instead of JSON.parse and ... by chillfox on Sunday January 23, 2022 @09:43PM (#30053109)
Not always, sometimes all other options are just wrong. Or you can auto detect the correct setting.
Re:I accidentally used YAML.parse instead of JSON.parse and ... by mikepurvis on Sunday January 23, 2022 @10:13PM (#30053302)
I understand the pragmatic reasons for it being the way it is, but I still wish TOML didn't require all strings to be quoted.
Re:I accidentally used YAML.parse instead of JSON.parse and ... by ryukoposting on Monday January 24, 2022 @12:13AM (#30053954)
This is why I like INI. It doesn't have these problems, because it doesn't try to wrangle the notion of nested objects (or lists) in the first place. The lack of a formal spec is a problem, sure, but it such a basic format that it's kind of self-explanatory.
Re:I accidentally used YAML.parse instead of JSON.parse and ... by Dylan16807 on Monday January 24, 2022 @12:47AM (#30054114)
When the problem is TOML not supporting easy nesting, a solution of "Don't nest." works just as well in TOML as it does in ini. It's not really an advantage of ini. Especially when a big factor in TOML not making it easy is that TOML uses the same kind of [section]\nkey=value formatting that ini does!
Re:I accidentally used YAML.parse instead of JSON.parse and ... by BiteCode_dev on Monday January 24, 2022 @07:16AM (#30056721)
You can use toml as a better ini by limiting yourself to the key / value schema. It still superior because:

- it has a spec

- it has other types than strings

- you can always decide you actually need nested data, and add them later

Re:I accidentally used YAML.parse instead of JSON.parse and ... by ryukoposting on Monday January 24, 2022 @06:45PM (#30065809)
I wrote an INI parser that has numerical, boolean, timestamp, MAC address, and IP address types ;) "advantages" of not having a spec!

Seriously: for application-specific config files, the lack of a formal spec can be kind of a nice thing. You can design your parser to the exact needs of your program, with data types that makes sense for your use case. Throw together a formal grammar for use in regression testing, and you're all set.

Obviously a formal spec is essential for data interchange, but that's why JSON exists. To me, YAML is in a gray area that doesn't need to exist. The same thing goes for TOML, but to a far lesser extent.

Re:I accidentally used YAML.parse instead of JSON.parse and ... by withinboredom on Monday January 24, 2022 @09:24AM (#30057907)
> it has other types than strings

But isn't the config file just a string?

Re:I accidentally used YAML.parse instead of JSON.parse and ... by chipsa on Monday January 24, 2022 @12:27PM (#30060829)
Everything gets serialized to a string of bytes. The point is that you can fail at parsing when the value doesn't make sense, rather than failing at some point in the future when you decide to use the value and it doesn't make sense. And if you have a defined schema, you can have your editor validate it against the schema when saving, so you don't accidentally have "FILENOTFOUND" in a Boolean.
Re:I accidentally used YAML.parse instead of JSON.parse and ... by addaon on Sunday January 23, 2022 @09:42PM (#30053106)
... lack of a hex float representation ...
Re:I accidentally used YAML.parse instead of JSON.parse and ... by zarzavat on Sunday January 23, 2022 @09:18PM (#30052911)
We do, it’s called TOML. The future is here it’s just not equally distributed.
Re:I accidentally used YAML.parse instead of JSON.parse and ... by SPBS on Sunday January 23, 2022 @10:14PM (#30053312)
TOML sucks for list of tables simply because they intentionally crippled inline tables to only be able to occupy one line. For ideology reasons ("we don't need to add a pseudo-JSON"). Unless your table is small, it's going to look absolutely terrible being all crammed into one line.

https://github.com/toml-lang/toml/issues/516

The official way to do list of tables is (look at how much duplication there is)

  [[main_app.general_settings.logging.handlers]]
    name = "default"
    output = "stdout"
    level = "info"

  [[main_app.general_settings.logging.handlers]]
    name = "stderr"
    output = "stderr"
    level = "error"

  [[main_app.general_settings.logging.handlers]]
    name = "access"
    output = "/var/log/access.log"
    level = "info"
vs

  handlers = [
    {
      name = "default",
      output =  "stdout",
      level = "info",
    }, {
      name = "stderr",
      output =  "stderr",
      level = "error",
    }, {
      name = "access",
      output =  "/var/log/access.log",
      level = "info",
    },
  ]
I would still reach for TOML first if I only needed simple key-value configuration (never YAML), but for anything requiring list-of-tables I would seriously consider JSON with trailing commas instead.
Re:I accidentally used YAML.parse instead of JSON.parse and ... by zarzavat on Monday January 24, 2022 @12:17AM (#30053976)
I see the point and this is certainly a drawback of TOML but for me this is something of a boundary case between configuration and data.

When configuration gets so complicated that the configuration starts to resemble structured data I tend to prefer to switch to a real scripting language and generate JSON instead.

Re:I accidentally used YAML.parse instead of JSON.parse and ... by CameronNemo on Monday January 24, 2022 @12:37AM (#30054068)
Expression languages like Nix, Jsonnet, Dhall, and Cue are really nice in these situations.
Re:I accidentally used YAML.parse instead of JSON.parse and ... by bin_bash on Sunday January 23, 2022 @10:39PM (#30053456)
for this reason I couldn't see a CI platform ever seriously consider TOML

(someone may point out to me a CI platform that relies on TOML—which I welcome)

Re:I accidentally used YAML.parse instead of JSON.parse and ... by colejohnson66 on Sunday January 23, 2022 @11:28PM (#30053750)
Rust is built on TOML. For better or worse.
Re:I accidentally used YAML.parse instead of JSON.parse and ... by notriddle on Monday January 24, 2022 @12:19AM (#30053980)
Do you mean Cargo? Because Cargo is not a CI system. You never embed shell commands in a Cargo.toml.

If you need to program complex logic to build a crate, you don’t write TOML. You write a build.rs file in actual Rust.

Re:I accidentally used YAML.parse instead of JSON.parse and ... by Too on Monday January 24, 2022 @12:49AM (#30054120)
If embedding shell commands in a configuration language is considered a CI system I think we are doomed.
Re:I accidentally used YAML.parse instead of JSON.parse and ... by Dylan16807 on Monday January 24, 2022 @12:51AM (#30054131)
> JSON with trailing commas

JSON5?

Re:I accidentally used YAML.parse instead of JSON.parse and ... by Tesl on Sunday January 23, 2022 @09:27PM (#30052987)
It's perfect until you do a lot of nesting..
Re:I accidentally used YAML.parse instead of JSON.parse and ... by donio on Sunday January 23, 2022 @11:18PM (#30053691)
...or any nesting. TOML sucks for anything non-trivial.
Re:I accidentally used YAML.parse instead of JSON.parse and ... by 41b696ef1113 on Sunday January 23, 2022 @09:40PM (#30053085)
It makes me sad every time I see a newly announced tool that went for YAML instead of TOML.
Re:I accidentally used YAML.parse instead of JSON.parse and ... by stickfigure on Monday January 24, 2022 @12:05AM (#30053918)
XML is still good.
Re:I accidentally used YAML.parse instead of JSON.parse and ... by js2 on Sunday January 23, 2022 @09:32PM (#30053025)
Hmm, it looks like it’s handled comments for at least a decade:

https://github.com/python/cpython/blame/d75a51bea3c2442f81d3...

Oh, maybe it’s this issue:

https://bugs.python.org/issue34132

If I’ve read it correctly, there was a regression from Python 2.x to 3.x such that you now need to format comments:

    #like this 
Instead of:

    # like this
(A space after the # isn’t accepted by the parser.)
Re:I accidentally used YAML.parse instead of JSON.parse and ... by dheera on Sunday January 23, 2022 @08:55PM (#30052770)

    try:
        try:
            import orjson as json
        except:
            try:
                import rapidjson as json
            except:
                try:
                    import fast_json as json
                except:
                    import json
        foo = json.loads(string)
    except:
        try:
            import yaml
        except:
            # try harder
            import os
            try:
                assert(os.system("pip3 install yaml") == 0)
            except:
                # try even harder
                try:
                    assert(os.system("sudo apt install python3-pip && pip3 install yaml") == 0)
                except:
                    assert(os.system("sudo yum install python3-pip && pip3 install yaml") == 0)
            import yaml
        try:
            foo = yaml.loads(string)
        except:
            try:
                ....
Re:I accidentally used YAML.parse instead of JSON.parse and ... by tomjakubowski on Sunday January 23, 2022 @09:08PM (#30052848)
Great idea.

  pip install --user yaml
increases the chances it will work
Re:I accidentally used YAML.parse instead of JSON.parse and ... by nrclark on Monday January 24, 2022 @08:10AM (#30057133)
A note to readers: it's not always a good idea to put automated software installation in a place that users don't expect it.

I've seen that kind of approach cause a ton of issues the moment that the software was used in a different environment than the author expected.

It's much better IMO to fail with a message about how to install the missing dependency.

Re:I accidentally used YAML.parse instead of JSON.parse and ... by dheera on Monday January 24, 2022 @06:59PM (#30065929)
This is why there should be a way to automatically install software into a sandboxed location, e.g. a virtualenv.

Considering we are having software drive cars today it should be trivial and I would say even arguably expected that software should be able to autonomously "figure out" how to run itself and avoid conflicts with other software since that's a trivial task in comparison to navigating city streets.

Re:I accidentally used YAML.parse instead of JSON.parse and ... by imoverclocked on Sunday January 23, 2022 @09:41PM (#30053092)
Brilliant! What license is this published under?
Re:I accidentally used YAML.parse instead of JSON.parse and ... by dheera on Sunday January 23, 2022 @10:09PM (#30053274)
Free Art License
Re:I accidentally used YAML.parse instead of JSON.parse and ... by mdaniel on Sunday January 23, 2022 @09:07PM (#30052843)
Tested on python what? I was curious to see what error that produced, figuring it would be some whitespace due to the difference between the list items, but using the yamlized python that I had lying around, it did the sane thing:

    PATH=$HOMEBREW_PREFIX/opt/ansible/libexec/bin:$PATH
    pip list | grep -i yaml
    python -V
    python <<'DOIT'
    from io import StringIO
    import yaml
    print(yaml.safe_load(StringIO(
    '''
        {
            "list": [
                {},
                    {}
            ]
        }
    ''')))
    DOIT
produces

    PyYAML                6.0
    Python 3.10.1
    {'list': [{}, {}]}
Re:I accidentally used YAML.parse instead of JSON.parse and ... by hoherd on Monday January 24, 2022 @12:17AM (#30053975)
With leading tabs it does not work.

  $ sed 's/\t/--->/g' break-yaml.json
  --->{
  --->--->"list": [
  --->--->--->{},
  --->--->--->{}
  --->--->]
  --->}
  $ jq -c . break-yaml.json
  {"list":[{},{}]}
  $ yaml-to-json.py break-yaml.json
  ERROR: break-yaml.json could not be parsed
  while scanning for the next token
  found character '\t' that cannot start any token
    in "break-yaml.json", line 1, column 1
  $ sed 's/\t/    /g' break-yaml.json | yaml-to-json.py
  {"list": [{}, {}]}
Re:I accidentally used YAML.parse instead of JSON.parse and ... by ingy on Monday January 24, 2022 @02:23PM (#30062570)
This is completely valid YAML.

YAML does not allow tabs in indentation, but the tabs in your example are not indentation according to the YAML spec productions.

You can see it clearly here against many YAML parsers: https://play.yaml.io/main/parser?input=CXsKCQkibGlzdCI6IFsKC...

As tinita points out, sadly PyYAML and libyaml implement this wrong.

See https://matrix.yaml.info/

Re:I accidentally used YAML.parse instead of JSON.parse and ... by tinita on Monday January 24, 2022 @01:24PM (#30061685)
That's because PyYAML doesn't implement the spec correctly.
Re:I accidentally used YAML.parse instead of JSON.parse and ... by MrPatan on Monday January 24, 2022 @03:31AM (#30054868)
Tabs are not valid JSON
Re:I accidentally used YAML.parse instead of JSON.parse and ... by zimpenfish on Monday January 24, 2022 @03:44AM (#30054952)
Do you have a link for that?

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe... says:

> Insignificant whitespace may be present anywhere except within a JSONNumber [forbidden] or JSONString [interpreted as part of the string]

And specifically lists tab as whitespace:

> The tab character (U+0009), carriage return (U+000D), line feed (U+000A), and space (U+0020) characters are the only valid whitespace characters.

More specifically, expanding https://datatracker.ietf.org/doc/html/rfc8259#section-2 gives an array as (roughly)

> ws %x5B ws value (ws %x2C ws value)* ws %x5D ws

Where `ws` explicitly includes `%x09`. Which seems to cover this case?

Re:I accidentally used YAML.parse instead of JSON.parse and ... by tonyg on Monday January 24, 2022 @04:23AM (#30055198)
Per RFC 8259:

      ws = *(
              %x20 /              ; Space
              %x09 /              ; Horizontal tab
              %x0A /              ; Line feed or New line
              %x0D )              ; Carriage return
Re:I accidentally used YAML.parse instead of JSON.parse and ... by Someone on Monday January 24, 2022 @04:15AM (#30055129)
The grammar in https://www.json.org/json-en.html disagrees. It has

  json
    element

  element
    ws value ws

  ws
    ‘0009’ ws
Re:I accidentally used YAML.parse instead of JSON.parse and ... by remram on Sunday January 23, 2022 @09:46PM (#30053121)
Edited with string escapes, the tab didn't make it through HN.

The error from PyYaml 5.3.1:

    yaml.scanner.ScannerError: while scanning for the next token
    found character '\t' that cannot start any token
      in "<unicode string>", line 4, column 1
Re:I accidentally used YAML.parse instead of JSON.parse and ... by notreallyserio on Sunday January 23, 2022 @10:45PM (#30053491)
If it continues to be hard to share, I suggest encoding it as a base64 string so folks can decode it into a file with exactly the right contents.
Re:I accidentally used YAML.parse instead of JSON.parse and ... by CameronNemo on Sunday January 23, 2022 @10:58PM (#30053578)
This is, unwittingly, the most YAML-relevant comment in this thread.
Re:I accidentally used YAML.parse instead of JSON.parse and ... by jwilk on Monday January 24, 2022 @09:17AM (#30057807)
Not base64, but this should be easy to reproduce:

  $ printf '{\n\t"list": [\n\t\t{},\n\t\t{}\n\t]\n}\n' > test.json

  $ jq < test.json 
  {
    "list": [
      {},
      {}
    ]
  }

  $ yamllint test.json 
  test.json
    2:1       error    syntax error: found character '\t' that cannot start any token (syntax)
Re:I accidentally used YAML.parse instead of JSON.parse and ... by ak217 on Monday January 24, 2022 @12:34PM (#30060935)
Thanks, I'm finally able to reproduce this.

It would be great if instead of the histrionic message on CPAN (which amusingly accuses others of "mass hysteria"), the author would just say "YAML documents can't start with a tab while JSON documents can, making JSON not a strict subset of YAML".

The YAML spec should be updated to reflect this, but I wonder if a simple practical workaround in YAML parsers (like replacing each tab at the beginning of the document with two spaces before feeding it to the tokenizer) would be sufficient in the short term.

Re:I accidentally used YAML.parse instead of JSON.parse and ... by ingy on Monday January 24, 2022 @02:42PM (#30062858)
> "YAML documents can't start with a tab while JSON documents can, making JSON not a strict subset of YAML"

But YAML can start with tabs. Tabs are allowed as separating whitespace in most of the spec productions but are not allowed as indentation. Even though those tabs look like indentation, the spec productions don't interpret them as such.

See my comment above and esp see https://play.yaml.io/main/parser?input=CXsKCQkibGlzdCI6IFsKC...

Note: the YAML spec maintainers (I am one) have identified many issues with YAML which we are actively working on, but (somewhat surprisingly) we have yet to find a case where valid JSON is invalid YAML 1.2.

Re:I accidentally used YAML.parse instead of JSON.parse and ... by ak217 on Monday January 24, 2022 @04:11PM (#30064106)
Thanks for the clarification. Let's fix it in PyYAML then :)

Speaking of PyYAML, I recently ran into an issue where I had to heavily patch PyYAML to prevent its parse result from being susceptible to entity expansion attacks. It would be nice to at least have a PyYAML mode to completely ignore anchors and aliases (as well as tags) using simple keyword arguments. Protection against entity expansion abuse would be nice too.

Re:I accidentally used YAML.parse instead of JSON.parse and ... by ak217 on Sunday January 23, 2022 @09:23PM (#30052957)
This parses fine as YAML in all the tools I've tried. Can you provide the specific versions of the libraries you're using?