Skip to content

Fix RFC 6570 reserved expansion for {+name} resource-path params#5

Merged
mhsdef merged 1 commit into
mainfrom
fix/reserved-expansion-path-params
Jul 2, 2026
Merged

Fix RFC 6570 reserved expansion for {+name} resource-path params#5
mhsdef merged 1 commit into
mainfrom
fix/reserved-expansion-path-params

Conversation

@mhsdef

@mhsdef mhsdef commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

What

Path params expressed as {+name} in a discovery template use RFC 6570 reserved expansion — the value is a resource name like projects/p/locations/l/processors/x whose / separators must survive into the URL. The generator was detecting these with:

String.ends_with?(path, "{#{wire}}")

which only matches the simple {name} form — never {+name}, and misses mid-path forms like {+name}:process. So every reserved param fell through to the simple, slash-encoding encoder, producing URLs like:

/v1/projects%2Fp%2Flocations%2Fus%2Fprocessors%2Fabc:process

which Google can't route. This broke core Document AI processing (process, batchProcess, operations polling) and async Vision operations polling in any consumer (e.g. Dozer), shipped in 0.1.0.

Fix

Detect reserved expansion by its actual marker — {+wire} in the path — and pick the encoder accordingly:

  • {+name} / {+parent}preserve / (~73 endpoints across the three clients: Doc AI processors/operations, Vision files/operations, etc.)
  • simple {object} / {bucket}percent-encode / (GCS object names must be encoded)

This also removes the old Storage-specific special-case for object/destinationObject, which was a band-aid over the same broken heuristic — the corrected rule handles it naturally.

Blast radius

Encoder-only change. Regenerated all three clients from the cached discovery specs (deterministic; diff is purely URI.encode predicates + formatting reflow). No model or API-surface changes.

Verification

  • Generator unit tests updated to lock in the corrected semantics (a {+name} param is reserved; a simple {object} is not) — the regression test that would have caught this. mix test → 60 pass.
  • Drove each regenerated client with a capture adapter:
    • Doc AI process…/v1/projects/p/locations/us/processors/abc:process ✅ literal slashes
    • Doc AI operations.get…/v1/projects/p/locations/us/operations/123
    • Vision operations.get…/v1/operations/abc123
    • Storage objects.get("bucket", "folder/sub/file.pdf")…/o/folder%2Fsub%2Ffile.pdf ✅ still encoded (GCS-correct)

Clients bumped to 0.1.1. Publish is manual (Hex passphrase/2FA).

Path params in a discovery `{+name}` template use reserved expansion — the
value is a resource name (projects/p/locations/l/processors/x) whose `/`
separators must survive into the URL. The generator was detecting these with
`String.ends_with?(path, "{name}")`, which only matches *simple* `{name}` and
never `{+name}` (and misses mid-path forms like `{+name}:process`). So every
reserved param got the simple, slash-encoding encoder, producing URLs like
/v1/projects%2Fp%2F...:process that Google can't route.

Detect reserved expansion by the actual marker — `{+wire}` in the path — and
encode accordingly:
- `{+name}` / `{+parent}` → preserve `/`  (Doc AI process/batchProcess/
  operations, Vision operations, etc. — ~73 endpoints across the 3 clients)
- simple `{object}` / `{bucket}` → percent-encode `/`  (GCS object names must
  be encoded; this drops the old Storage-specific special-case, which was a
  workaround for the same broken heuristic)

Regenerated all three clients from the cached specs (encoder-only diff).
Verified end-to-end: Doc AI/Vision resource URLs now carry literal slashes,
GCS object paths stay percent-encoded. Bumped clients to 0.1.1.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@mhsdef mhsdef merged commit d9d7640 into main Jul 2, 2026
8 checks passed
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.

1 participant