Getting around Lotus Notes Domino (Web) Error 4354: Cannot remove NotesDocument when it is the Document Context

Deleting Domino Doc’s

In the process of doing some work I came across this problem, and after searching / googling the usual suspects did not find a resolution, until I remembered how I done this in the past. I’m going to document my solution as a aid to other and for the next time I have a brain freeze.

This works for Lotus Notes Domino R5.x.

When does this error occur : When doing Domino Web work, the easy, standard, way of executing a agent from a Web Form is to create a formula hotspot or button with the formula :

1
@Command([ToolsRunMacro]; "myAgent")

Which will execute the “myAgent” Agent, and the other half of this is have LotusScript code along the lines of :

1
2
3
4
5
6
7
8
9
10
<br />Sub Initialize
<br />     
<br />  Dim session As New NotesSession
<br />  Dim sessiondb As NotesDatabase
<br />  Set sessiondb = session.CurrentDatabase
<br /> 
<br />  Dim sessionDoc As notesDocument
<br />  Set sessionDoc = session.DocumentContext   
<br />                ........' the rest of the code
<br />

Now after doing what ever other stuff you what / need to do, you what to delete the Document from which you called the agent so you :

1
2
3
<br />                Call sessionDoc.remove(True)
<br />
<br />

Which would do ordinarily do exactly that, but this time blows up and doesn’t remove the document. ACK!

After trying a few things and then RTFM’ing, I discover that at the end of the help page for DocumentContext property it says :

You cannot use the encrypt and remove methods on the Document object returned by DocumentContext…

So, I’m SOL, right? Not so fast….

I’ve got 2 ways around this:

1) rather that do a remove in the first agent, mark it with a status indicating it needs to be deleted…

1
2
3
<br />              Set sessionDoc.Status = "DeleteMe"
<br />              Call sessionDoc.Save ( True, False )   
<br />

The Documents can either be manually deleted (from a Lotus client and special view, by the appropriate user) or you can create a scheduled agent to do a search for document marked for deletion and zap them. Like this….

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
               ......
<br />               Dim tmpDoc as NotesDocument    
<br />  Dim Doc As NotesDocument
<br />  Dim Dc As NotesDocumentCollection
<br />  Dim searchFormula As String
<br />  searchFormula = |SELECT Status="DeleteMe"|     
<br />  Set DC = db.Search( searchFormula, Nothing,  0 )
<br />  Set Doc = DC.GetFirstDocument      
<br />  Do While Not(Doc Is Nothing )
<br />      Set tmpDoc = Doc
<br />      Set Doc = DC.GetNextDocument( Doc )    
<br />      Call tmpDoc.remove(True)
<br />  Loop
<br />  .......
<br />

Two additional things 2 keep in mind. Make sure any user views or lookups wouldn’t find the document marked with the

1
sessionDoc.Status = "DeleteMe"

. Run the actual delete agent as often as needed or a server resources allow.

I don’t like the above solution because I need to worry about the showing up where it shouldn’t or going though any views might show the document. For a existing application, there is a risk that a deleted document will be visible. The other reason I don’t like it is because It requires an higher level user to remember to open a view to manually delete (and I’m busy enough as it is) or the server resources to run yet another scheduled agent (and the servers are the only thing busier than me).

2) The workaround is to invoke the agent another way, to modify the agent to make it to work by NOt using the

1
@Command([ToolsRunMacro]; "myAgent")

Command and the DocumentContext property.

Rather, Launch the agent via it url (either building a HREF or using @URLOpen(“pathtoMyAgent/MyAgent?OpenAgent&ID=123”), pass on the url line a ID to the document, then within Agent, parse the url to get the Id and do a look to get the NotesDocument which is then removable.

I’ll post some code to parse the url line paramters shortly. A quick google failed to find anything useful. Hopeful this will save the life of some newbie.

Update : here that promised code: Very simple LotusScript function to parse value on url line. enjoy.

3 Replies to “Getting around Lotus Notes Domino (Web) Error 4354: Cannot remove NotesDocument when it is the Document Context”

  1. I can’t believe you actually went thru all this trouble.
    The context document is the in-memory representation of the web page. it’s the CGI-post-data represented in a notes document dress. The context is not saved to the database unless you explicitly save it in the agent (context.save()) or by formula (@Command(FileSave])).

    Anyway, if you still disagree, try this solution to delete it:
    First obtain the UniversalID or the NoteID, and save it in a variable.
    Next assign the object to nothing (set context = nothing),
    then lookup the document by its noteid or universalid from the db, and this should make it safe to delete it..

    Too bad i’m too late (almost 4 years after ur article’s date), but better late than never 😉

    thx

    Sam -/-

  2. Sam, DocumentContext is read only.
    There is another workaround: call another agent by method Run and pass document NoteID as parameter. This agent would delete doc.

  3. Ondrej Vojta, isn’t read only. You can set context = nothing, also you can .ReplaceItemValue. But…
    If it’s a newly created document you cannot pass document NoteID as parameter, cause there’s NO NOTEID, rather than DocUNID.
    I haven’t checked if the second workaround of the main topic is true, but selecting a newly creating document for Encrypting/Deleting is available only like this way:
    1 step: call doc.ReplaceItemValue (“VisibleItem”, False) ‘ to make it unvisible for users and appear in some closed view (can also be Authors field mpdification).
    2 step: Create an agent, run through the view, Delete/Encrypt your docs and make ’em visible.

Leave a Reply to Ondrej VojtaCancel reply