Wednesday, February 1, 2012

SPListItem provided is not compatible with a Publishing Page

I have been hitting my head against a wall lately with a custom master page and some custom sites. There appears to be an incompatibility between the 2. Since they come from separate sources, finding out where to point the finger is a little tricky. My custom master page makes use of Publishing, Feature Stapling, among other things.

The behaviour is that when I edit a community page and then click publish, it would throw an exception

System.ArgumentException: Invalid SPListItem. The SPListItem provided is not compatible with a Publishing Page.   
 at Microsoft.SharePoint.Publishing.PublishingPage.GetPublishingPage(SPListItem sourceListItem)    
 at Microsoft.SharePoint.Publishing.Internal.WebControls.PublishingPagePublishHandler.RaisePostBackEvent(String eventArgument)    
 at System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument)    
 at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)

I have yet to figure out what is going on here. However here are some other observations

$web = Get-SPWeb <SPWeb URL>

This returns false despite the Publishing tab being there and the SharePoint Server Publishing site feature is activated.

So, ignoring the False, I continue with this:
$publishingweb = [Microsoft.SharePoint.Publishing.PublishingWeb]::GetPublishingWeb($web)
$publishingpages = $publishingweb.GetPublishingPages()

This throws an exception:

Exception calling "GetPublishingPages" with "0" argument(s): "The site is not valid. The 'Pages' document library is missing."
At line:1 char:53
+ $publishingpages = $publishingweb.GetPublishingPages <<<< ()
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : DotNetMethodException

... but the Pages document library does indeed exist and I do have administrative rights on it.

I also try the following:

$pages = $web.Lists | Where-Object {$_.Title -eq "Pages"}
$page = $pages.Items | Where-Object {$_.Name -eq "default.aspx"}

... and get False which I would expect given the results from above. What doesn’t make sense is that this default.aspx page does have a Publish tab on it.

I then decided to try the IsPublishingWeb again, but without the custom master page. This is still giving me False. So, I guess I will start pointing the finger towards my custom site ...


  1. Try this

    $web = get-spweb http://site-collection/path-to-affected-site
    $correctId = $web.Lists["Pages"].ID
    $web.AllProperties["__PagesListId"] = $correctId.ToString()

    $web.AllProperties["__PublishingFeatureActivated"] = "True"

    1. You mad my day Debjit.. Thanks I am searching for this for so many times

    2. Very nice na?

    3. Many thanks from me as well! Just helped me solve the same issue

    4. This worked a treat, added it to a powershell script that was auto creating sites from templates :)

      Si (uk)

  2. Thanks a lot, Debjit! Spent a day on this until I found your post.

  3. Debjit thanks this also solved my problem instantly. I've been struggling with about 30 sites experiencing the same issue.

  4. Debjit, I too appreciate your contribution, it solved my problem.

  5. When running $web.AllProperties["__PagesListId"] = $correctId.ToString()
    I receive an error "You cannot call a method on a null-valued expression"

    Any ideas?

    1. What are the values of $web and $correctId?

  6. Hello. Great Post! this solution worked on one of the sites but not working on another:( After calling first $web.Update() I get following error:
    Exception calling "Update" with "0" argument(s): "Item has already been added.
    Key in dictionary: 'H?↑' Key being added: 'H?↑'"
    At line:1 char:12
    + $web.Update <<<< ()
    + CategoryInfo : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : DotNetMethodException

    Any ideas?

    1. It's been a long time since I looked at this. Off the top of my head, perhaps your $web object is stale? Maybe try getting it again with $web = Get-SPWeb $web.Url and do the second update?