POST /fields rejects a subtype property like RichText unless the body names the subtype
A POST …/fields body is deserialised as the base type SP.Field unless it says otherwise. FieldTypeKind: 3 does not change that, so a property that only exists on the subtype fails with 400 (measured with RichText; other subtype-only properties fall under the same type rule). Create the column with CreateFieldAsXml, or add '@odata.type': '#SP.FieldMultiLineText' (OData v4 client). Check every column after a loop of creates: the text columns go through and the list is left half-built.
Tělo POST …/fields se čte jako základní typ SP.Field, pokud neřekne jinak. FieldTypeKind: 3 na tom nic nemění, takže vlastnost, která existuje až u podtypu, skončí chybou 400 (změřeno s RichText; ostatní vlastnosti jen z podtypu spadají pod totéž pravidlo typu). Sloupec založ přes CreateFieldAsXml, nebo přidej '@odata.type': '#SP.FieldMultiLineText' (klient OData v4). Po smyčce zakládání ověř všechny sloupce: textové projdou a seznam zůstane napůl založený.
Symptom
A hidden log list is created on first use, then its columns are added in a loop. The list exists afterwards, but only the single-line text columns are there; the first write to a multi-line column fails because the column is missing.
The failing request:
POST /_api/web/lists(guid'…')/fields
Accept: application/json;odata=nometadata
Content-Type: application/json;odata=nometadata
{ "Title": "Detail", "FieldTypeKind": 3, "RichText": false }
400 Microsoft.SharePoint.Client.InvalidClientQueryException:
The property 'RichText' does not exist on type 'SP.Field'.
Make sure to only use property names that are defined by the type.
Why
The fields collection accepts any field kind, so the entity set's type is SP.Field. FieldTypeKind is just a property of that type; it does not select a derived type for deserialisation. Without a type annotation the server validates the body against SP.Field, which has no RichText.
Single-line text columns usually carry nothing but Title and FieldTypeKind, so they pass and hide the problem.
Fix
CreateFieldAsXml takes the schema as XML and works with a plain nometadata body (measured live, 200, column created with RichText = false):
await fetch(`${listApi}/fields/CreateFieldAsXml`, {
method: 'POST',
headers: { Accept: 'application/json;odata=nometadata', 'Content-Type': 'application/json;odata=nometadata', 'X-RequestDigest': digest },
body: JSON.stringify({ parameters: {
SchemaXml: '<Field Type="Note" Name="Detail" StaticName="Detail" DisplayName="Detail" RichText="FALSE" NumLines="6" />',
Options: 0
} })
});
Alternatively, name the subtype in the body. With an OData v4 client (SPFx SPHttpClient sends OData-Version: 4.0) that is '@odata.type': '#SP.FieldMultiLineText'; from a bare fetch (OData v3) it needs __metadata and odata=verbose instead – see __metadata in the body requires verbose.
Prevention
- After a create loop, read the list's fields back and fail loudly if any is missing, instead of discovering it on the first write.
- Run the first-use path once on a clean test site before release: a list that already has the columns never exercises it.