> Where would they come from?

Logging components being the worst offenders immediately spring to me. Especially the ones that receive data points over a network in heterogenous environments. syslog running on a flavour ABC of UNIX receives an input from a locally running app that has a buffer overrun, the app has previously accepted a longer than permitted input and dumped the actual log entry + all trailing the garbage until the app encountered ASCII NULL into syslog. syslog does not care about the correctness of the received entry and, hence, is not affected and, say, diligently dumps it into a locally stored log file. The log parser is now screwed. I can think of similar examples outside log parsers, too, such interoperability related between different systems.

Granted, it has become less of a problem in recent years due the number of UNIX varieties having gone extinct or languages and frameworks considerably improving in the overall quality, but it has not completely disappered. Just less than a couple of years ago, a sloppy developer was dumping the PDF file content (in binary!) into the log file. The logger survived, but the log parser had a severe case of indigestion.

> If you're doing that a lot, the code tends to be fragile. If you use cut for instance, it breaks the second the data you're working it changes. Program decided column needs to be 5 characters wider? Now the stuff you're looking for is not there anymore.

You are absolutely correct. This is why I do not use «cut» and treat all columns as variable length patterns that can be matched using a regular expression in «sed». It is immune to column width changes as long as the column delimiters are known that are used as start and stop characters. «cut» is only useful when parsing fixed-length formats, such as SWIFT MT940/MT942, where the column width is guaranteed to remain fixed. «cut» is just overcomplicates everything and makes scripts prone to unpleasant breakages.

> That's how you end up with "ifconfig is old, everyone switch to ip now". At some point a program's output may be parsed by so much stuff that any change risks breaking something, and it forces it to remain static for eternity.

The cited reason to switch to «ip» was an unrelated to parsing, if I recall it correctly. But otherwise you are correct, the community has a proven track record of resisting changes in the output format due to the risk of breaking gazillions of cobbled together and band-aided shell scripts.

> No, my point is that the producer is free to improve without risking the consumers.

This is not guaranteed. If the producer changes the content of the structure or merely extends an existing structure, then consumers will continue to consume. However, if the producer decides to changes the structure of the output content itself, the breakage problem still persists. Changes to the content structure not infrequently occur when person A hands over to person B something called a piece XYZ that have been working on before, and person B has a different way of doing the same thing.

> If your command that produced IPv4 addresses adds support for IPv6, it doesn't suddenly break every script that relies on precise lengths, line numbers and columns.

Anything that is tightly coupled with precisely defines things is going to break, there is no scripting solution possible, I am afraid. E.g. if the script author relies on the maximum IPv4 address length (AAA.BBB.CCC.DDD) to never exceeed 15 characters or a specific format of IPv4 addresses, the added suppport for and IPv6 addresses appearing in the output will certainly break the script. Again, one possible solution is to treat all values as variable length patterns that are enclosed within delimiters and do not try to interpet the column content.