Surfaced by the #7893 dev while sweeping docs for that retirement. Deliberately not folded into PR #8496 — it is pre-existing, generic, and as much about job as about field, so widening the retirement PR to cover it would have been scope creep. Filing instead.
The gap
content/docs/api/metadata-api.mdx:49 documents:
PUT /meta/:type/:name — "Create or update a metadata item"
with no mention that some types refuse the create half. The page names no type, so it is not wrong about any particular one — it is incomplete about the verb.
Why it matters more now than it did
This was already incomplete: #4509 retired job's runtime create the same way.#7893 makes it two types (field joins job), and the mechanism is now an established pattern rather than a one-off — allowRuntimeCreate: false on a DEFAULT_METADATA_TYPE_REGISTRY entry means PUT answers 403 NOT_CREATABLE for a brand-new name while still accepting updates to an existing one.
So a reader following this page hits a 403 the page gives them no way to anticipate, and the refusal message is the first place they learn the rule. The refusal messages are good — #7893 gave field a remedy naming the route that actually works — but a reference page should not require you to fail first.
Suggested fix
One caveat sentence on that entry: creates are gated per type by allowRuntimeCreate, some types accept updates but refuse brand-new names, and the refusal names the working route. Point at wherever the per-type flags are readable rather than enumerating types inline, so the sentence does not go stale the next time one is retired.
⛔ Do not enumerate field and job by name unless the enumeration is generated — a hand-written list of retired types is the same shape that goes stale, and this card exists because the page did not track a change.
Explicitly NOT in scope
Verified while filing
The #7893 sweep found the surviving route is documented in two places, so this is a completeness gap rather than a dead end for readers: content/docs/api/metadata-api.mdx:49 itself carries an object-typed body example, and content/docs/concepts/metadata-lifecycle.mdx:114 now states explicitly that writing the object with the field in fields is how a field is added.
Related
#7893 · PR #8496 · #4509 (the job retirement that made this incomplete first) · ADR-0049
Surfaced by the #7893 dev while sweeping docs for that retirement. Deliberately not folded into PR #8496 — it is pre-existing, generic, and as much about
jobas aboutfield, so widening the retirement PR to cover it would have been scope creep. Filing instead.The gap
content/docs/api/metadata-api.mdx:49documents:with no mention that some types refuse the create half. The page names no type, so it is not wrong about any particular one — it is incomplete about the verb.
Why it matters more now than it did
This was already incomplete: #4509 retired
job's runtime create the same way.#7893 makes it two types (fieldjoinsjob), and the mechanism is now an established pattern rather than a one-off —allowRuntimeCreate: falseon aDEFAULT_METADATA_TYPE_REGISTRYentry meansPUTanswers403 NOT_CREATABLEfor a brand-new name while still accepting updates to an existing one.So a reader following this page hits a 403 the page gives them no way to anticipate, and the refusal message is the first place they learn the rule. The refusal messages are good — #7893 gave
fielda remedy naming the route that actually works — but a reference page should not require you to fail first.Suggested fix
One caveat sentence on that entry: creates are gated per type by
allowRuntimeCreate, some types accept updates but refuse brand-new names, and the refusal names the working route. Point at wherever the per-type flags are readable rather than enumerating types inline, so the sentence does not go stale the next time one is retired.⛔ Do not enumerate
fieldandjobby name unless the enumeration is generated — a hand-written list of retired types is the same shape that goes stale, and this card exists because the page did not track a change.Explicitly NOT in scope
content/docs/releases/v17.mdx— it carries ajobretirement row and nofieldrow. That is correct and untouched: release notes compile centrally from changesets, and meta-field-write-inert: an acceptedfieldPUT never reaches the object — a runtime-created field is storedvalid=trueand is absent fromfieldsforever #7893's changeset is the input. Do not edit it.fieldPUT never reaches the object — a runtime-created field is storedvalid=trueand is absent fromfieldsforever #7893 shippedNESTED_TYPE_REMEDYsofield's refusal namesPUT /api/v1/meta/object/:object; that is working as intended and is not what this card is about.Verified while filing
The #7893 sweep found the surviving route is documented in two places, so this is a completeness gap rather than a dead end for readers:
content/docs/api/metadata-api.mdx:49itself carries an object-typed body example, andcontent/docs/concepts/metadata-lifecycle.mdx:114now states explicitly that writing the object with the field infieldsis how a field is added.Related
#7893 · PR #8496 · #4509 (the
jobretirement that made this incomplete first) · ADR-0049