In working through an issue with workflow I stumbled across an interesting 'feature' of workflow and MOSS.
Essentially I have a "Project Sites" root web where I am creating child sites via a workflow:
Project Sites
Child Site 1
List 1
List 2
In these child sites I am creating some lists and setting alerts on them based upon things that happen in the workflow.
In attempting to create an alert on a list, I received a "List does not exist" error. In stepping through the code and inspecting all the objects everything seemed valid. SPList is a valid list in the site, SPUser is a valid user.
I went down the path of it being a security issue because that would make sense but security was set correctly, the process account of the timer service and the iis process account is an owner of the list. I have struggled with this for awhile before figuring it out. I even thought this might have something to do with the fact that I just created the site from workflow so I put a delay in to dehydrate the workflow and then rehydrate it again before trying to set the alerts.
The relevant lines of code:
...
SPUser user = workflowproperties.Web.EnsureUser("...");
this.SetAlert(user,list,evtType,evtFreq,alertType, true);
private void SetAlert(SPUser sPUser, SPList sPList, SPEventType eType, SPAlertFrequency frequency, SPAlertType aType, bool omitFromMe)
{
if (!HasAlert(sPUser, sPList))
{
SPAlert sPAlert = sPUser.Alerts.Add();
sPAlert.AlertType = aType;
sPAlert.Title = sPList.Title;
sPAlert.EventType = eType;
if (omitFromMe)
{
sPAlert.Filter = "<Query><Neq><Value type='string'>" + sPUser.Name + "</Value><FieldRef Name='Editor/New'/></Neq></Query>";
}
sPAlert.AlertFrequency = frequency;
sPAlert.User = sPUser;
sPAlert.List = sPList;
sPAlert.Status = SPAlertStatus.On;
sPAlert.AlwaysNotify = false;
sPAlert.Update(true);
}
}
Very straightforward really.
It turns out that the issue was where I got the SPUser object from. Like most programmers I tend to do things consistently and I usually use workflowproperties.Web.EnsureUser(...) to get my SPUser objects. As it turns out if you get your User Object from a different web then the parent of the list you are attempting to create an alert on you will get this error. Go figure.
What worked:
SPUser user = list.ParentWeb.EnsureUser("...");
this.SetAlert(user,list,evtType,evtFreq,alertType, true);