Skip to content

SPFx REST API returns 404 when adding Field Link to Content Type on M365 Developer Tenant #10489

@Edinshall01

Description

@Edinshall01

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."}}}

Metadata

Metadata

Assignees

Labels

sharepoint-developer-supportsharepoint-developer-supporttype:bug-confirmedConfirmed bug, not working as designed / expected.type:bug-suspectedSuspected bug (not working as designed/expected). See “type:bug-confirmed” for confirmed bugs.type:invalid-not-dev-issueThis repo+issue list is for SharePoint development topics. Non-dev issues will be closed.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions