-
Notifications
You must be signed in to change notification settings - Fork 1k
Description
Target SharePoint environment
SharePoint Online
What SharePoint development model, framework, SDK or API is this about?
💥 SharePoint Framework
Developer environment
None
What browser(s) / client(s) have you tested
- 💥 Internet Explorer
- 💥 Microsoft Edge
- 💥 Google Chrome
- 💥 FireFox
- 💥 Safari
- mobile (iOS/iPadOS)
- mobile (Android)
- not applicable
- other (enter in the "Additional environment details" area below)
Additional environment details
SharePoint Environment: SharePoint Online : Microsoft 365 E5 Developer (without Windows and Audio Conferencing)
Tenant Type: Microsoft 365 Developer Program Tenant
Framework: SharePoint Framework (SPFx) v1.18.2
Tooling: React, @pnp/sp, sp-http-client
Describe the bug / error
When using the SharePoint REST API from an SPFx web part to provision lists and content types, all operations succeed except for adding a field link to a content type. The standard, documented endpoints for this operation consistently fail with a 404 Not Found error. Further attempts to use alternative endpoints lead to a circular pattern of contradictory 400 Bad Request errors, suggesting the API is either unavailable or not functioning as expected on M365 Developer Tenants.
The provisioning logic successfully:
Creates lists and libraries (sp.web.lists.ensure()).
Creates site columns (sp.web.fields.createFieldAsXml()).
Creates site content types (sp.web.contentTypes.add()).
The process fails only at the final step of linking the site columns to the newly created content type.
Sequence of Failures:
Primary Failure on Standard Endpoints:
A POST request to the standard endpoints for adding a field link fails with a 404 Not Found.
Endpoints:
.../_api/web/contenttypes('...id...')/fieldlinks/add
.../_api/web/contenttypes('...id...')/fields/addfieldbyinternalnameusingmutation
Payload: A valid SP.FieldLinkCreationInformation or SP.AddFieldOptions object.
Error: 404 Not Found with message: {"error":{"code":"-1, Microsoft.SharePoint.Client.ResourceNotFoundException","message":{"lang":"en-US","value":"Cannot find resource for the request add."}}}
Diagnostic Failure on Collection Endpoint:
As a diagnostic step, a POST request was sent to the base /fieldlinks collection endpoint, which led to a series of contradictory 400 Bad Request errors as we attempted to satisfy the API's demands.
Attempt 1: POST to .../_api/web/contenttypes('...id...')/fieldlinks with payload {"fieldInternalName": "..."}.
Error: 400 Bad Request - "An entry without a type name was found, but no expected type was specified."
Attempt 2: Added __metadata to the payload: {"__metadata": {"type": "SP.FieldLink"}, "fieldInternalName": "..."}.
Error: 400 Bad Request - "The property 'fieldInternalName' does not exist on type 'SP.FieldLink'."
Attempt 3: Corrected the property name based on the error: {"__metadata": {"type": "SP.FieldLink"}, "Name": "..."}.
Error: 400 Bad Request - "Value cannot be null. Parameter name: parameters"
Attempt 4: Wrapped the payload in a parameters object as requested by the error: {"parameters": {"__metadata": {"type": "SP.FieldLink"}, "Name": "..."}}.
Error: This returned to the original 400 Bad Request error: "An entry without a type name was found...", creating an unresolvable loop.
This entire sequence demonstrates that the standard endpoints appear to be missing, and the alternative collection endpoint is behaving in a broken and contradictory manner.
/* The code being used */
// This function builds the list of endpoints to try
private buildFieldLinkEndpoints(ctId: string): Array<{ url: string; strategy: 'fieldLink' | 'mutation' }> {
const baseUrl = this.props.context.pageContext.web.absoluteUrl.replace(//$/, '');
const encodedCtId = encodeURIComponent(ctId);
return [
{ url: ${baseUrl}/_api/web/contenttypes('${encodedCtId}')/fieldlinks/add, strategy: 'fieldLink' },
{ url: ${baseUrl}/_api/web/contenttypes('${encodedCtId}')/fieldlinks/Add, strategy: 'fieldLink' },
{ url: ${baseUrl}/_api/web/contenttypes/getbyid('${encodedCtId}')/fieldlinks/add, strategy: 'fieldLink' },
{ url: ${baseUrl}/_api/web/contenttypes/getbyid('${encodedCtId}')/fieldlinks/Add, strategy: 'fieldLink' },
{ url: ${baseUrl}/_api/web/contenttypes('${encodedCtId}')/fields/addfieldbyinternalnameusingmutation, strategy: 'mutation' },
{ url: ${baseUrl}/_api/web/contenttypes/getbyid('${encodedCtId}')/fields/addfieldbyinternalnameusingmutation, strategy: 'mutation' }
];
}
// This function makes the failing POST request
private async postFieldLink(endpoint: { url: string; strategy: 'fieldLink' | 'mutation' }, fieldLinkPayload: string, internalName: string, contentTypeName: string, fieldId: string): Promise {
let body: string;
if (endpoint.strategy === 'fieldLink') {
body = fieldLinkPayload; // The full SP.FieldLinkCreationInformation payload
} else { // 'mutation'
body = JSON.stringify({
parameters: {
'__metadata': { type: 'SP.AddFieldOptions' },
FieldInternalName: internalName,
FieldId: fieldId,
AddFieldOptions: 0,
AddToDefaultView: false
}
});
}
try {
const response = await this.props.context.spHttpClient.post(endpoint.url, SPHttpClient.configurations.v1, {
headers: {
Accept: 'application/json;odata=verbose',
'Content-Type': 'application/json;odata=verbose',
'odata-version': ''
},
body
});
if (response.ok) {
// This block is never reached
return true;
}
const errorText = await response.text();
// This always logs a 404 error
console.error(`SharePoint rejected '${internalName}' for '${contentTypeName}' (status ${response.status}): ${errorText}`);
return false;
} catch (err) {
console.error(`Exception when calling ${endpoint.url} for field '${internalName}': ${String(err)}`);
return false;
}
}
Steps to reproduce
In an SPFx web part on an M365 Developer Tenant, create a site column (e.g., 'MyTestColumn').
Create a new site content type (e.g., 'MyTestContentType').
Attempt to add the site column to the content type by making a POST request to one of the standard REST API endpoints (.../fieldlinks/add or .../fields/addfieldbyinternalnameusingmutation).
Observe the 404 Not Found error response.
Expected behavior
The POST request should succeed with a 200 OK or 201 Created status, and the site column should be linked to the site content type.
Actual behavior
The POST request fails with a 404 Not Found error. The error message from the server is:
{"error":{"code":"-1, Microsoft.SharePoint.Client.ResourceNotFoundException","message":{"lang":"en-US","value":"Cannot find resource for the request add."}}}