When you don’t pay enough attention to the docs…

…it’s easy to get your fingers burned. I was looking at an issue with personalisation recently, which reminded me that those little details in the docs, which change between versions can often be the most important ones.

Note: The community has dived in and updated the Stack Exchange answer discussed below since I wrote this. I’ve changed my links to refer to the original versions, to try and avoid making this post’s links confusing.

I was working with a client who wanted to deploy Sitecore to PaaS in an “XP running as XM” style. They wanted to use simple in-session personalisation, but they didn’t want to have the expense of running the xConnect service in their Azure resource group when they didn’t really need it. That’s a scenario that’s discussed in the documentation, but when I was talking to the client, what I had in my head was a Sitecore Stack Exchange answer I’d read on this topic from some time back.

The client came back to me and said this wasn’t working though – so I had to do some more investigation.

The issue:

I didn’t have direct access to the client’s site, so the best way to investigate this was to reproduce the issue locally.

On a vanilla install of Sitecore v9.2 XP, I set up a simple personalisation test. I made one page that triggered a goal, and another which had a personalised component on it which would change state based on whether the goal had been triggered that session or not. With the default setup of Sitecore that all worked fine. But once I deployed the basic patch implied by the Stack Exchange answer above, it stopped working:

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/" xmlns:set="http://www.sitecore.net/xmlconfig/set/"  xmlns:role="http://www.sitecore.net/xmlconfig/role/">
    <sitecore>
        <settings>
            <setting name="Xdb.Enabled" set:value="false" />
            <setting name="Xdb.Tracking.Enabled" set:value="true" />
        </settings>
    </sitecore>
</configuration>

With xdb disabled but tracking enabled the personalisation rule never triggered. The page rendered ok, but always in the default personalisation state.

After a bit of rubber-ducking with colleagues, I realised that while the page was rendering without error, there was a pile of exceptions in the logs for each page request:

4032 16:28:39 ERROR Cannot start analytics.
Exception: System.InvalidOperationException
Message: Tracker.Current is not initialized
Source: Sitecore.Analytics
   at Sitecore.Analytics.Pipelines.StartAnalytics.StartTracking.Process(PipelineArgs args)
   at (Object , Object )
   at Sitecore.Pipelines.CorePipeline.Run(PipelineArgs args)
   at Sitecore.Analytics.XConnect.Diagnostics.PerformanceCounters.OperationPerformanceMonitorExtensions.<>c__DisplayClass1_0.<Monitor>b__0()
   at Sitecore.Analytics.XConnect.Diagnostics.PerformanceCounters.OperationPerformanceMonitorExtensions.Monitor[T](OperationPerformanceMonitorBase monitor, Func`1 operation)
   at Sitecore.Analytics.Pipelines.HttpRequest.StartAnalytics.Process(RenderLayoutArgs args)

2556 16:28:40 ERROR Cannot create tracker.
Exception: System.Reflection.TargetInvocationException
Message: Exception has been thrown by the target of an invocation.
Source: mscorlib
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
   at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at Sitecore.Reflection.ReflectionUtil.CreateObject(Type type, Object[] parameters)
   at Sitecore.Configuration.DefaultFactory.CreateFromTypeName(XmlNode configNode, String[] parameters, Boolean assert)
   at Sitecore.Configuration.DefaultFactory.CreateObject(XmlNode configNode, String[] parameters, Boolean assert, IFactoryHelper helper)
   at Sitecore.Configuration.DefaultFactory.CreateObject(XmlNode configNode, String[] parameters, Boolean assert)
   at Sitecore.Configuration.DefaultFactory.CreateObject(String configPath, String[] parameters, Boolean assert)
   at Sitecore.Configuration.DefaultFactory.CreateFromReference(XmlNode configNode, String[] parameters, Boolean assert)
   at Sitecore.Configuration.DefaultFactory.CreateObject(XmlNode configNode, String[] parameters, Boolean assert, IFactoryHelper helper)
   at Sitecore.Configuration.DefaultFactory.CreateObject(XmlNode configNode, String[] parameters, Boolean assert)
   at Sitecore.Configuration.DefaultFactory.GetInnerObject(XmlNode paramNode, String[] parameters, Boolean assert)
   at Sitecore.Configuration.DefaultFactory.AssignProperties(XmlNode configNode, String[] parameters, Object obj, Boolean assert, Boolean deferred, IFactoryHelper helper)
   at Sitecore.Configuration.DefaultFactory.CreateObject(XmlNode configNode, String[] parameters, Boolean assert, IFactoryHelper helper)
   at Sitecore.Configuration.DefaultFactory.CreateObject(XmlNode configNode, Boolean assert)
   at Sitecore.Pipelines.CorePipelineFactory.GetObjectFromType(XmlNode processorNode)
   at Sitecore.Pipelines.CorePipelineFactory.GetProcessorObject(XmlNode processorNode)
   at Sitecore.Pipelines.CoreProcessor.GetMethod(Object[] parameters)
   at Sitecore.Pipelines.CorePipeline.Run(PipelineArgs args)
   at Sitecore.Pipelines.DefaultCorePipelineManager.Run(String pipelineName, PipelineArgs args, String pipelineDomain, Boolean failIfNotExists)
   at Sitecore.Pipelines.DefaultCorePipelineManager.Run(String pipelineName, PipelineArgs args, String pipelineDomain)
   at Sitecore.Analytics.Pipelines.EnsureSessionContext.EnsureSessionContextPipeline.<>c__DisplayClass4_0.<Run>b__0()
   at Sitecore.Analytics.XConnect.Diagnostics.PerformanceCounters.OperationPerformanceMonitorExtensions.<>c__DisplayClass1_0.<Monitor>b__0()
   at Sitecore.Analytics.XConnect.Diagnostics.PerformanceCounters.OperationPerformanceMonitorExtensions.Monitor[T](OperationPerformanceMonitorBase monitor, Func`1 operation)
   at Sitecore.Analytics.DefaultTracker.EnsureSessionContext()
   at Sitecore.Analytics.Pipelines.CreateTracker.GetTracker.Process(CreateTrackerArgs args)
   at (Object , Object )
   at Sitecore.Pipelines.CorePipeline.Run(PipelineArgs args)
   at Sitecore.Pipelines.DefaultCorePipelineManager.Run(String pipelineName, PipelineArgs args, String pipelineDomain, Boolean failIfNotExists)
   at Sitecore.Pipelines.DefaultCorePipelineManager.Run(String pipelineName, PipelineArgs args, String pipelineDomain)
   at Sitecore.Analytics.Tracker.Initialize()

Nested Exception

Exception: System.Reflection.TargetInvocationException
Message: Exception has been thrown by the target of an invocation.
Source: mscorlib
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
   at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at Sitecore.Reflection.ReflectionUtil.CreateObject(Type type, Object[] parameters)
   at Sitecore.Configuration.DefaultFactory.CreateFromTypeName(XmlNode configNode, String[] parameters, Boolean assert)
   at Sitecore.Configuration.DefaultFactory.CreateObject(XmlNode configNode, String[] parameters, Boolean assert, IFactoryHelper helper)
   at Sitecore.Configuration.DefaultFactory.CreateObject(XmlNode configNode, Boolean assert)
   at Sitecore.Configuration.DefaultFactory.GetProviders[TProvider,TCollection](List`1 nodes)
   at Sitecore.Configuration.DefaultFactory.GetProviders[TProvider,TCollection](String rootPath, TProvider& defaultProvider)
   at Sitecore.Configuration.ProviderHelper`2.ReadProviders()
   at Sitecore.Configuration.ProviderHelper`2.get_Provider()
   at Sitecore.Analytics.Data.ContactRepository..ctor()

Nested Exception

Exception: System.InvalidOperationException
Message: Cannot use DataAdapterProvider as xDB is disabled.
Source: Sitecore.Analytics.DataAccess
   at Sitecore.Analytics.DataAccess.DataAdapterProvider..ctor(Boolean checkXdb)
   at Sitecore.Analytics.XConnect.DataAccess.XConnectDataAdapterProvider..ctor(IScopedXdbContextFactory contextFactory, DefinitionManagerFactory definitionManagerFactory, ModelConverterBase modelConverter, BaseLog log, XConnectProviderPerformanceContextBase performanceContext)
   at Sitecore.Analytics.XConnect.DataAccess.XConnectDataAdapterProvider..ctor()

That suggested I was doing something wrong. The config patch was supposed to have disabled xdb, but the exception above suggests something’s still trying to use those APIs. But it the error is annoyingly non-specific about what…

The answer:

That lead me to a pile of googling, which eventually made me realise that the Stack Exchange answer is out of date. The up-to-date documentation makes reference to another setting:

Adding the change to the web.config to disable EXM as well as xdb resolved the log exception. And it allowed the personalisation to work correctly without xdb.

So the moral of this story is that those little un-related looking bits of config that get added into the docs are important. So make sure you’re checking the right version for the release you’re currently working on.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.