Vetrix Docs

Issues — issue_type Write/Read Asymmetry

The issue API is asymmetric for the issue type field: writes take a flat issue_type_id scalar, while reads return a nested issue_type object.

Summary

Direction Field shape Example
Write (POST /issues, PATCH /issues/{n}) flat scalar issue_type_id (UUID string) {"issue_type_id":"<uuid>"}
Read (GET /issues, GET /issues/{n}, list) nested issue_type object {"issue_type":{"id":"<uuid>","name":"Bug","slug":"bug",...}}

A request that sends the read shape (issue_type — nested object, or a bare string slug) on a write is rejected with HTTP 400 and the exact error message:

issue_type is read-only; use issue_type_id

This is true for both POST (create) and PATCH (update).

Why the asymmetry exists

Reads return the fully-hydrated issue_type object so a client can render the type's name, colour, and slug without a second lookup. Writes take only the canonical issue_type_id UUID because the type catalogue is server-owned — clients select an existing type by id; they do not define type attributes inline. Accepting a nested issue_type object on write would be ambiguous (is {"issue_type":{"name":"Bug"}} a lookup, an upsert, or a rename?), so the API rejects it rather than silently dropping the field.

How the rejection is enforced

The issue create and update endpoints reject unknown fields. The request body is parsed with strict decoding, so any field that is not part of the write contract fails with HTTP 400. The write contract declares issue_type_id and not issue_type, so a payload that carries an issue_type key is rejected.

For the issue_type key specifically, the 400 body's top-level error is the canonical read-only message, and detail names the correct field:

{
  "error": "issue_type is read-only; use issue_type_id",
  "detail": "use \"issue_type_id\":\"<uuid>\" (canonical) — bare string slugs and nested {id} objects are not accepted"
}

Any other unknown field returns the generic unknown-field error in error with a hint in detail. The top-level error field is the one a client should branch on.

Client guidance

  • To set or change an issue's type, send "issue_type_id":"<uuid>" on POST /api/v1/repos/{owner}/{repo}/issues (issue_type_id is required when creating an issue) or PATCH /api/v1/repos/{owner}/{repo}/issues/{number}.
  • Do not echo a read response's nested issue_type object back on a write — extract .issue_type.id into issue_type_id.
  • Bare string slugs ("issue_type":"bug") are also rejected — resolve the slug to a type UUID first.