generate: feed the generator JSON — the flag I added does not work on our pin

658493a added -DmaxYamlCodePoints to lift snakeyaml's 3145728 code-point
ceiling. I verified it on generator 7.24.0, which is what the C++ lane uses, and
did not verify it on 7.14.0, which is what THIS FILE pins for every other
language. It does not work there: 7.14.0 ships an older swagger-parser that
ignores the property. Java regeneration failed after 9m27s with the same
misleading "Issues with the OpenAPI input" the flag was supposed to prevent.

So the fleet was blocked on regenerating and the fix was cosmetic. The real fix
is not to raise the ceiling but to stop going near it: swagger-parser only hands
YAML to snakeyaml, and the JSON path is Jackson, which has no such cap. -i takes
either format.

Measured rather than assumed, because "it happens to be under the limit" is not
a fix — the JSON of this document is 3,144,674 code points, 1054 UNDER the
ceiling, which would have made a coincidence look like a solution. Padded to
3,684,674 (539 KB OVER) it still validates clean on 7.14.0. The JSON path does
not have the ceiling at all.

as_json() converts once, in main(), for every language. The temp file is
deliberately not written back to the repo: there is one document, and it is
hanzo.yaml.

Side effect worth recording: java generation went from failing at 9m27s to
succeeding in 12s. The YAML parse was not merely failing, it was thrashing.

hanzo-cpp/sdk's own scripts/generate.sh now does the same one thing rather than
carrying the flag, so there is one mechanism and not two. Verified by
--check: the generated C++ tree is byte-identical across the swap.

Co-authored-by: Hanzo Dev <[email protected]>
This commit is contained in:
2026-07-31 16:33:54 -07:00
co-authored by Hanzo Dev
parent e7f488c53c
commit 7c59566eee
+30 -11
View File
@@ -16,6 +16,7 @@ convention.
import argparse
import concurrent.futures as futures
import hashlib
import json
import os
import shutil
import subprocess
@@ -52,6 +53,33 @@ def jar(version):
ARTIFACTS = ("__pycache__", ".mypy_cache", ".pytest_cache", ".ruff_cache", "node_modules")
def as_json(path):
"""The document as JSON, because YAML has a ceiling and JSON does not.
swagger-parser hands a YAML document to snakeyaml, which refuses anything
over 3 * 1024 * 1024 = 3145728 code points. hanzo.yaml passed that mark at
1bac13f (3,654,449) and the failure does not say so: the parser logs
SnakeException, silently falls through to the SWAGGER 2.0 compat reader, and
dies with "Issues with the OpenAPI input", which reads like a malformed
spec. It is not — the document validates at 0 errors.
`-DmaxYamlCodePoints` lifts the cap, and it is NOT the fix: the property is
honoured by the swagger-parser in generator 7.24.0 and IGNORED by the one in
7.14.0, which is the version this file pins. Feeding JSON instead avoids
snakeyaml altogether — measured, not assumed: a JSON 539 KB OVER the ceiling
validates clean on 7.14.0. The generator reads either format from -i, so
this costs one temp file and removes a ceiling the document will keep
growing into.
Deliberately not written back to disk as a second committed artifact. There
is one document, and it is hanzo.yaml.
"""
with tempfile.NamedTemporaryFile("w", suffix=".json", delete=False,
dir=os.environ.get("TMPDIR")) as f:
json.dump(yaml.safe_load(open(path)), f)
return f.name
def digest(path):
"""Content of a tree as {relpath: sha256}; a file is a one-entry tree."""
if os.path.isfile(path):
@@ -96,16 +124,7 @@ def emit(name, cfg, spec, version, out):
"apiDocs=false", "modelDocs=false", "apiTests=false", "modelTests=false"]
glob += [f"{k}={v}" for k, v in cfg.get("global", {}).items()]
cmd = [
# -DmaxYamlCodePoints: swagger-parser hands the document to snakeyaml,
# which refuses anything over 3 * 1024 * 1024 = 3145728 code points.
# hanzo.yaml passed that mark at 1bac13f (3,654,449) and the parser does
# not say so plainly — it logs SnakeException, silently falls through to
# the Swagger 2.0 compat reader, and dies with "Issues with the OpenAPI
# input", which reads like a malformed spec. It is not: the document
# validates at 0 errors and 0 warnings. A parser default, nothing else,
# and it stops EVERY language at once — so it is set here, once, rather
# than discovered separately in seven repos.
"java", "-Xmx2g", "-DmaxYamlCodePoints=99999999", "-jar", jar(version), "generate",
"java", "-Xmx2g", "-jar", jar(version), "generate",
"-g", cfg["generator"],
"-i", spec,
"-o", out,
@@ -171,7 +190,7 @@ def main():
langs = sorted(conf["sdks"]) if (a.all or not a.langs) else a.langs
if a.repo and len(langs) != 1:
ap.error("--repo takes exactly one language")
spec = os.path.join(ROOT, conf["spec"])
spec = as_json(os.path.join(ROOT, conf["spec"]))
version = str(conf["generator"])
def one(name):