...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.
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...
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.
↑ Back to top