Wednesday, February 25, 2026

Heft + SPFx < 1.22 = Runtime Errors (and the Fix) when running "serve" (heft start)

If you’ve recently converted an SPFx project to use Heft, but your SharePoint Framework version is below 1.22.x, you may hit a pair of opaque runtime errors that don’t clearly point to the real problem.

The Symptoms

You’ll see something like:

Uncaught runtime errors:

ERROR

Unknown promise rejection reason

    at handleError (https://localhost:4321/dist/...)



And sometimes (see below my guess as to when):

Uncaught runtime errors:

ERROR

Old FRE behavior is disabled

    at get._deferLoadingFeatureHostControl (...)



This looks like something fundamentally broken in your web part. In reality, the issue is a tooling/runtime mismatch.

Root Cause

When you migrate an SPFx project to use Heft, you are effectively aligning with the newer SPFx build pipeline.

However:

  • Heft-based builds assume SPFx 1.22.x+

  • Projects running SPFx 1.21.x or earlier are not fully compatible

  • The failure manifests at runtime, not build time

This is why everything may compile successfully, but the web part fails during execution.

To make things more interesting:

If you are using:

import { ???? } from '@pnp/spfx-controls-react';
@pnp/spfx-controls-react

You may encounter additional friction after upgrading, because at the time of writing, some PnP controls have not been fully aligned with SPFx 1.22.x typings.

I am not 100% sure, but I think this caused the second issue (the Old FRE behavior is disabled error)

The Fix

Step 1 — Upgrade to SPFx 1.22.x

Upgrade your project to:

"@microsoft/sp-component-base": "1.21.1",
"@microsoft/sp-core-library": "1.21.1",
"@microsoft/sp-lodash-subset": "1.21.1",
"@microsoft/sp-office-ui-fabric-core": "1.21.1",
"@microsoft/sp-property-pane": "1.21.1",
"@microsoft/sp-webpart-base": "1.21.1",

Version:

1.22.x

Then:

Delete node modules folder, delete the package-lock.json file, and run npm install.

Rebuild and repackage.

This resolves the Heft runtime mismatch.


After Upgrading: PnP Controls Typing Issue

Once upgraded, you may see TypeScript errors with PnP React controls — especially around context.

Example:

<FilePicker
context={this.props.context}
/>

You may get a typing error because the control expects a slightly different context type under 1.22.x.

Temporary Workaround

Cast the context to any:

<FilePicker
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- SPFx 1.22 temporary compatibility workaround for PnP controls
context={this.props.context as any}
/>

Yes — this will raise a lint warning.
Yes — you are intentionally suppressing it.
Yes — it is acceptable as a temporary compatibility shim until the PnP controls fully align.

Monday, August 04, 2025

Content types missing in Site Pages library "New" dropdown, and not able to create pages

Symptoms

User goes to site pages, clicks the "new" button and only sees "link" and "folder"
Library settings show the site page content type or other content types that were added to the library.
User can still create pages if they go to an existing page and use the new button there, but once a page gets created there is no way to change its content type.

Solution

As a global 365 admin, go to the sharepoing admin site, click Settings > Pages > and then "Allow users to create new modern pages"

 Notes

This should also be a warning for admins who turn this off - it does not actually prevent users from creating modern pages - I was still able to do so using both the "new" button in a page and also using powershell.

Thursday, April 21, 2022

Copying sharepoint multi user field values from one item to another in powerapps

'Target Field Name':ForAll(varSourceItem.'Source Field Name',{

                    '@odata.type': "#Microsoft.Azure.Connectors.SharePoint.SPListExpandedUser",

                    Claims: Claims,

                    Department: Department,

                    DisplayName: DisplayName,

                    Email: Email,

                    JobTitle: JobTitle,

                    Picture: Picture

                })

Tuesday, March 29, 2022

Mass-changing powerapps controls settings

One of the most annoying powerapps restrictions is when you add a form (edit or view), all cards exist independently from each other and there is no way to "theme" them to look the same. 

So if I have an application with lots of forms and I want to have all the labels be a specific font, font size and weight, I have to do it on each label, in each form....uggghh!

The solution I came up with is:
  1. Install VSCode and the powerapps extension in vscode (Power Apps Guide - Code - The new easier way to pack and unpack canvas app source code - Power Apps Guide - Blog)
  2. download your app, and extract it using the extension (see link above for detailed instructions):
    pac canvas unpack --msapp .\myapp.msapp --sources .\myapp\
  3. Decide on a single label that will be your master label, or a variable name that will contain your defaults. we will need the name of that label or the variable for later - lets call it XYZ for now.
  4. open the app folder in vs code, and do a find and replace with the following settings:
In the find box, turn on reg ex and type:
^(\s*DataCardKey.*As label:)

this will find all lines that start with "DataCardKey" and end with "As label:".
By default these are the lines that microsoft powerapps will add to the code when adding a data card. This is the definition of the header (label) of the data card.

In the replace box, type:
$1
                    FontWeight: =XYZ.FontWeight
                    Color: =XYZ.Color

This will add to all instances of the "datacardkey?? as label:" the fontweight and color (in this example) to copy from your "master" label. Alternatively you can create app wide variables for the weight\color or other properties.
You will probably need to fix some problems that the vscode will highlight.

Next, re-pack the app:
pac canvas pack --sources .\ --msapp c:\code\myapp.msapp

Then upload it to a new canvas app (or override the existing one)
Create a canvas app, click "file">"open".

Now if you change the properties you configured on the master label, everything else will flow.

Wednesday, March 24, 2021

Making the workbench full width

I often am frustrated by the forced max width of the workbench - which inhibits my web part testing. To overcome this, I add the following in the componentDidMount of my web part during development phase:


$("#workbenchPageContent").attr("style","max-width:inherit");

Wednesday, March 17, 2021

Getting user ID by email in REACT SPFX web part

Missed me? I'm back!


Here is a small function I whipped up for React web parts that need the user id.
 /**
     * Fetches the user ID for the specified user
     * @param email the email for the user
     * @returns a promise containing the user ID in the site collection
     * example:
     * var userID = await this.getUserIDByEmail(this.props.wpContext.pageContext.user.email);
     */
    private async getUserIDByEmail(email:string):Promise<number>
    {
        var url = `${this.props.wpContext.pageContext.site.absoluteUrl}/_api/web/siteusers?$filter=Email eq '${email}'`;
        var userData:any = await  Query.GetQueryData(this.props.wpContext,url);
        return userData.value[0].Id;
    }

this refers to a class I created called Query where I put some code to help me do queries:


export default class Query {
  public static async GetQueryData(contextWebPartContexturlstring) {
    var deferred = $.Deferred();
    console.log(`running query '${url}'`);
    let _nometaOptISPHttpClientOptions = {
      headers: { 'Accept': 'application/json;odata=nometadata''odata-version': '''Content-type': 'application/json;odata=verbose' }
    };
    context.spHttpClient.get(urlSPHttpClient.configurations.v1_nometaOpt).then(
      (responseSPHttpClientResponse=> {

        if (response.status == 200) {
          console.log("got query results");
          if (response.headers.get("content-type").indexOf("atom") > -1) {
            console.log("Got xml instead of json on " + url);
            response.text().then((text:string=> {
              deferred.resolve(text);
            });
          }
          else {
            response.json().then((jsondataJSON=> {
              deferred.resolve(jsondata);
            });
          }
        }
        else {
          console.log("error getting query results!");
          console.log(response.status);
        }
      }, (errany=> {
        debugger;
        console.log("error getting query results!");
        console.log(err);
      });
    return deferred;
  }
}

Wednesday, June 12, 2019

Restricting a User Picker field to only selecting SharePoint groups

 After a lot of research, I couldn't find the answer, so I wrote one myself.
To change a person field in sharepoint that is configured to allow "users and groups" to only allow groups, you need to inject code that changes the picker settings after the page is loaded.

Code below:



$(document).ready(function(){
//wait for the initialisation of the sharepoint script 

  SP.SOD.executeFunc('sp.js', 'SP.ClientContext', function(){
//call our special function with the field's internal name
    SetGroupOnly("myfieldinternalname");
  });
});

function SetGroupOnly(fieldName)
{
//make sure there is a control for that field on the page
  if($("div[id^='"+fieldName+"_']").length>0)
  {
    //wait for the initialisation of the control to finish
    WaitForControl("div[id^='"+fieldName+"_'][id$='$ClientPeoplePicker']", function(){
//get the people picker control object
      var peoplepicker = SPClientPeoplePicker.SPClientPeoplePickerDict[$("div[id^='"+fieldName+"_'][id$='$ClientPeoplePicker']").attr("id")];
//set the type to SPGroup
      peoplepicker.PrincipalAccountType = "SPGroup";
      peoplepicker.PrincipalAccountTypeEnum = 8;
      peoplepicker.ResolvePrincipalSource = 15;
      peoplepicker.SearchPrincipalSource = 15;
    });
  }
}



function WaitForControl(controlSelector, returnFunction)
{
  if($(controlSelector).length>0)
    returnFunction();
  else
    setTimeout(function(){
      WaitForControl(controlSelector,returnFunction)},50);    
}

Sunday, November 18, 2018

User is in SharePoint Group but doesn't get permissions

Found this today - a user shows up in a SharePoint group, but when you do a permission check the user doesnt have permissions to resources in sharepoint that the group has permissions to.
One explanation to this that I found is when the user was added to the group using the API (REST, JSOM, CSOM) by specifying the user's login name (domain\username). Turns out that adds the user to the group, but not the correct user....so it looks right, but it isn't. what is the correct user? you have to add the claims token "i:0#.w|" before the domain\username to properly add the user.
This off course applies to the code that adds the users. As far as I can tell you will have to remove the incorrect users, and then add them again either manually or using code.


Tuesday, July 25, 2017

When Cumulative doesn't mean Cumulative

 So, I just tried adding a new server to a farm, after patching it to the same level as all other servers in the farm (April 2017 CU).
Surprisingly, the SharePoint configuration wizard told me off, saying the server is missing the December 2016 CU.

Yes, that is right - the April 2017 CU does not include the CU that was released 5 months before it...Cumulative? nope!

Monday, June 01, 2015

Taxonomy field value doesnt set

We had a puzzle today, which we were sure was an issue with the document property parser in SharePoint. Every time we tried to set the value of a specific column using either our existing powershell script or an event handler that works on every other library in the system, the document would be updated with the property value, but after a second we'd refresh the page and see the value went back to null.


It was frustrating! I was sure it was because the document had an empty value in the document properties that was overriding the value from my code - despite the fact that my code is implemented with a delay to ensure it runs after the parser.


We troubleshooted several ways and couldn't find the solution...until we noticed something weird when we were looking at the content type schema - the taxonomy field was set to support multiple values! our code was specifically written for that field, which is not supposed to support multiple values. Some nasty little elf went into the column setting in the library and changed my precious from its normal settings. Setting it back and everything went to normal.

Moral of the story - since setting a taxonomy field's value in code is different if the field supports multivalue or not, make sure either your code is robust enough to handle a nasty user making a change, or tell your users to keep their hands to themselves!

Thursday, June 12, 2014

Creating links to documents inside document sets - BUG

This is a bug a client of mine found in SharePoint 2010, and I verified on 2013 and Office 365 (as of today - not yet fixed).

The issue is when you create a link to a document inside a document set. If you are not familiar with this - users can create links inside document libraries, using a content type called "Link To Document". You can also create document sets - which is a special type of folder. To do so, add the two content types to a document library:




You then also have to configure the document set content type to accept links to documents in the document set settings under the content type settings:



The problem is when you create a document set, and in it you then create a link to document:


The result is that the users get redirected to the wrong URL, and instead of seeing the actual document set they started from, with the new link (or any document that is already in the document set) the users see a default view of a generic document set - not the one they started from:

The reason for this is different in 2010 and 2013. I have yet to pinpoint the reason for the issue in 2013, but in 2010 the issue is that the URL when creating a new link to document has two "RootFolder" parameters, and that confuses the server when the users click "OK" to save the link and to get redirected back. Instead of seeing the document set, they see the default document set home page - with no parameter to tell the server which document set to actually display the contents of.


I have created a workaround for 2010, and am yet to modify it for 2013 (since the behaviour in 2013 is slightly different, though the results are the same). The workaround is to use javascript to detect if we got to the current page from the edit form, and if the current page is a document set home page and if the current page parameters have two question marks in them. If so, redirect the user, removing the second "&RootFolder=" parameter. This will not work in 2013 since the url there doesnt have parameters after creating the link to document.

Here is an example of the code. To inject it I used a farm level feature that added a ScriptLink to all pages in the farm. The script link was to a .js file that contained the following code:

function FixDocumentSetRedirect() {
    if (document.referrer.indexOf("EditForm.aspx") > 0 && document.location.href.toLowerCase().indexOf("docsethomepage.aspx?id=") > 0 && document.location.href.toLowerCase().indexOf("docsethomepage.aspx?id=") < document.location.href.indexOf("?")) {
        var source = document.referrer;
        source = source.substring(source.indexOf("Source=") + "Source=".length);
        var firstRootFolder = source.indexOf("&RootFolder=");
        var secondRootFolder = source.indexOf("&RootFolder=", firstRootFolder + 1);
        if (secondRootFolder > firstRootFolder) {
            source = source.substring(0, secondRootFolder);
        }
        alert(source);
        
        document.location.href = source;
    }
}

_spBodyOnLoadFunctionNames.push("FixDocumentSetRedirect"); 



Wednesday, April 09, 2014

Users able to open documents using links, even without permissions

Recently I had to troubleshoot an issue where end-users were able to open links to documents they had no permissions to open. If they tried opening the library they got the "access denied" message that is expected, but clicking a link directly to a document in the library resulted in the document either opening up in the browser, or downloaded. We double checked the documents did not have item level security, and they didn't.

What a puzzle!

Turns out that those libraries were provisioned by code, and the code set a property on the library called "AllowEveryoneViewItems" (msdn documentation). This property, when set to true, means that anyone- even unauthenticated users, will be able to download and view items in the list or library - even without permissions.

The reason to turn it to true is when dealing with anonymous sites - for example, if you have an internet site and you want to put links to documents from pages, but you don't want users to be able to browse the library itself.

Wednesday, June 19, 2013

SharePoint 2013 Book is ready to purchase

If you are looking for a sharepoint 2013 end-user specific book, look no further

Monday, May 20, 2013

Activating the Document ID feature by code causes document sets welcome pages to show each web part twice

This is a weird one - I have a feature, that when activated loops over a list of other features and activates them - using "Force" :

site.Features.Add(currentFeatureID, true);


This works fine on most sites, but in Document Center sites, where the document ID feature is already activated document sets in the site suddenly show the web parts on the welcome page twice. I debugged it, and it turns out that this happens when the document ID feature is the culprit. However, this doesn't happen if I activate the ID feature using powershell.


My only solution at the moment is to check if the feature is already activated before activating it. This stopped the problem, but doesn't explain it.

Sunday, May 19, 2013

Finding if a site column exists in a site, by ID

Scenario - you have an ID of a site column (SPField belonging to SPWeb)and you want to find out if there is a field by that ID in the collection.


Problem: if you try something like:


web.Fields[fieldID] == null




The result is an exception if the field doesnt exist. What a shame.

The solution is to use the Contains method of the Fields collection:


web.Fields.Contains(fieldID)


*Thanks Ofer Gal for pointing this out.

Thursday, February 21, 2013

Fields not sortable or filterable

A client alarmed me today, showing me that in one document library a field I created didn't allow users to filter or sort on it. I couldn't find why in that library it did that, while the same site column in all other libraries allowed filtering and sorting. Checking in sharepoint manager showed no difference between the field in the different libraries - so I was stuck on that one as well.

After a while it dawned on me - the difference between the libraries was that in the one that was misbehaving the column was specified as a key filter - to help users filter and sort on it from the metadata navigation panel. This disabled the sort and filter in the list view.

Learn something new everyday = high blood pressure for the rest of your life.

Sunday, January 13, 2013

Folder sorting in views

A client has alerted me to an unexpected behavior of list views where folders are involved.
The client wanted to make sure the folders are always on the top of the view, regardless of sort order, and, looking at the settings of the view it should have happened. However, seemingly at random some document libraries stopped doing that, while other libraries were fine.
After digging into it a bit, I realised what the issue is: enabling and disabling folders.

You see, the client had custom folder content types added to some of the document libraries, and in those libraries the client wanted to make sure the users don't create folders of the built-in content type using the "New Folder" button in the ribbon. To achieve this, they changed the setting in document library advanced settings to not "Make "New Folder" command available?".
Turns out that when this setting is set to "no", there are other ramifications than just not showing the new folder command. It also tells views to behave as it there are no folders - and treat all folders items. Result - in those libraries folders were sorted with items, and were not at the top of the views. Makes sense if you consider that that setting is mapped to the SPList.
EnableFolderCreation
in code - meaning it tells the list that folders are not available - even though you can still create folder using the "new" button and choose a content type that inherits from folder.
To resolve this, we made sure the "Make "New Folder" command available?" option is always set to "yes", but we activated a feature that disabled the new folder button itself - not touching the document library setting.

Sunday, January 06, 2013

SharePoint error 0x81020030 Invalid file name

If you try to upload a file to a sharepoint document library, and get an error about invalid file name or url, it could be that your problem has nothing to do with the file name - it could be a problem with a corrupt column that has been added to the document library.

In my case, I had to remove column by column until I found that the issue goes away if I remove a calculated column that I created using a feature (using CAML), and the XML definition of the column was missing a critical attribute - the ResultType attribue. Adding that attribute to my XML solved the problem.

Thursday, November 15, 2012

Getting the full name of a feature by code

When you use the SPFeatureDefinition object, and you want to get the name of the feature you are manipulating, the "DisplayName" property of that object returns a string that is NOT the display name of the feature as you see it when you view the feature list on the site. For example, the display name of "Publishing Infrastructure" feature will be returned as "PublishingSite".

The reason is that the feature list is showing a localized version of the display name - so depending on the language of the site, the name of the feature displayed will be different than the display name the object exposes.

So, how to get the full display name? the SPFeatureDefinition object has a function called "GetTitle", which, when specifying a language, will return the full name of the feature. The following code sample loops over all features installed in the local farm, and using the English locale:

 foreach (SPFeatureDefinition def in SPFarm.Local.FeatureDefinitions)
                    {
                        CultureInfo locale = CultureInfo.CreateSpecificCulture("en-US");   
                                                if (def.Hidden)
                            continue;
                        Console.WriteLine(def.GetTitle(locale) + ":" + def.Id.ToString());
                        }

Wednesday, September 05, 2012

Repeated authentication prompts from SharePoint

In the past few weeks I had two clients with a similar issue - both had some users expiriencing multiple requests for user name and password whenever they accessed the site. With one client entering the user name and password sometimes worked, and sometimes would request 10 times and then show the site, and sometimes would just result in a blank, empty page. With the other client, they would always get to a "internet explorer cannot display the web page" error page.

If you research the issue on your favorite search engine, you will find a lot of references to authentication providers (forms, claims and so on), registry issues, trusted sites or intranet zone settings or maybe the users are on the server and the loopback check was not disabled. Well, none of these were valid in the case of these two clients - for one thing, the users were not on the server - they were on their desktops. For another thing - even when the site was added to trusted sites it still happened. Most perpelxingly - with one client it only happenned to users on windows XP, not the users who were on Windows7...

After wasting a lot of time troublshooting the issue, I finally realised what must be different between those users and the rest, and why it sometimes worked and sometimes it didn't - it was the proxy server!

Turns out both clients had a proxy server, with proxy settings deployed to desktops via group policy. The proxy would behave differently every time it was asked for the new web site address, and would cause an authentication prompt for each image on the page. In one organisation, the proxy settings that were deployed were different for Windows XP users - which explains why only those users expirienced the issues.

The solution? I told the network admins to either add the web site to the proxy exception list in IE (via group policy) or fix the proxy server itself.