LotusScript for HCL Domino
LotusScript is the scripting language for HCL Domino (formerly IBM Lotus Notes/Domino). It resembles Visual Basic but has critical differences. Target platform: Domino 14, backend classes only (web-based applications).
CRITICAL: LotusScript Is NOT Visual Basic
Claude frequently confuses LotusScript with VBA/VB6. These differences will cause broken code if ignored:
| Feature |
LotusScript |
Visual Basic |
| Default parameter passing |
ByRef (always assume ByRef) |
ByVal |
| Associative arrays |
List type (built-in) |
No equivalent (use Dictionary) |
| Iterate collections |
ForAll loop |
No equivalent (use For Each) |
| String functions |
StrLeft, StrRight, StrLeftBack, StrRightBack |
No equivalent |
| Run formula language |
Evaluate("@Formula") |
No equivalent |
| Include files |
%Include "filename" |
No equivalent |
| Module scope |
Option Public (makes module members public) |
Public on each member |
| Require declarations |
Option Declare |
Option Explicit |
| Object cleanup |
Delete statement |
Set x = Nothing |
| Print in web agents |
Writes to HTTP response |
Writes to console/debug |
| Property syntax |
Property Get/Set/Let with no parentheses on Get |
Parentheses on Get |
No Set for assignment |
Set only for object references |
Set for objects, Let for values |
| String variant |
Use $ suffix: Left$(), Mid$() |
No $ variants |
| Class events |
Sub New / Sub Delete |
Class_Initialize / Class_Terminate |
| Error object |
Err, Erl, Error$ (line number tracking) |
Err.Number, Err.Description |
| Boolean values |
True = -1, False = 0 |
Same, but watch for implicit conversion |
Scope: Backend Classes Only
This project uses Domino as a web application server. All code runs in agents and script libraries triggered by HTTP requests. Never use front-end (UI) classes:
- DO NOT USE:
NotesUIWorkspace, NotesUIDocument, NotesUIView, NotesUIDatabase
- USE:
NotesSession, NotesDatabase, NotesDocument, NotesView, etc.
Web Agent Essentials
Sub Initialize
Dim session As New NotesSession
Dim db As NotesDatabase
Dim doc As NotesDocument
Set db = session.CurrentDatabase
Set doc = session.DocumentContext ' CGI variables and POST data
' Read query string
Dim queryString As String
queryString = doc.GetItemValue("Query_String_Decoded")(0)
' Output HTTP response
Print "Content-Type: application/json"
Print ""
Print |{"status": "ok"}|
End Sub
Key web agent rules:
Print writes to the HTTP response body — first print Content-Type, then a blank line, then body
session.DocumentContext provides CGI variables as fields on a document
- Pipe
| characters delimit strings that can contain quotes
- Web agents run as the authenticated user (or Anonymous for unauthenticated)
Common Gotchas
- GetItemValue returns a Variant array — always index with
(0) for single values
- Save is not automatic — always call
doc.Save True, False after modifications
- Nothing checks — always check
If Not (doc Is Nothing) before using objects
- String comparison — use
StrCompare or LCase$() for case-insensitive comparison
- Arrays are 0-based by default — use
Option Base 1 to change, or use LBound/UBound
- Lists vs Arrays — Lists are associative (keyed by string), Arrays are indexed by integer
- Variant vs typed variables — always use
Option Declare and type your variables
- RichText fields — cannot be read with
GetItemValue, must use GetFirstItem and cast to NotesRichTextItem
- Date handling — use
NotesDateTime objects, not native date functions, for Domino date fields
- Chr(0) is CRLF — in Domino,
Chr(0) acts as Chr(10)+Chr(13) (newline), not a null byte as in standard ASCII. Long-standing Domino behavior since the 1990s.
- Large POST bodies are chunked — Domino splits large
Request_Content into numbered fields (request_content_000, request_content_001, etc.), each ~32-64K depending on platform
- NotesHTTPRequest.ResponseCode is a String — returns the full status line (e.g.,
"HTTP/1.1 200 OK"), NOT an integer. Use InStr(http.ResponseCode, "200") > 0 to check status — never http.ResponseCode = 200
Reference Files
- syntax-fundamentals.md — Data types, control flow, error handling, strings, arrays, Lists
- domino-object-model.md — Backend class hierarchy and usage (NotesSession → NotesDocument)
- domino-modern-features.md — Domino 10-14: DQL, JSON classes, HTTPRequest, LS2J, MIME
- web-agent-patterns.md — Web agent patterns: CGI vars, JSON output, CRUD, error handling
1---2name: lotusscript3description: Use when writing LotusScript code, Domino agents, script libraries, or working with HCL Domino backend classes. Use when encountering NotesSession, NotesDatabase, NotesDocument, or any Notes* classes. Use when building web agents that return HTML or JSON from Domino.4---56# LotusScript for HCL Domino78LotusScript is the scripting language for HCL Domino (formerly IBM Lotus Notes/Domino). It resembles Visual Basic but has critical differences. Target platform: **Domino 14**, backend classes only (web-based applications).910## CRITICAL: LotusScript Is NOT Visual Basic1112Claude frequently confuses LotusScript with VBA/VB6. These differences will cause broken code if ignored:1314| Feature | LotusScript | Visual Basic |15|---------|-------------|--------------|16| Default parameter passing | **ByRef** (always assume ByRef) | ByVal |17| Associative arrays | **List** type (built-in) | No equivalent (use Dictionary) |18| Iterate collections | **ForAll** loop | No equivalent (use For Each) |19| String functions | `StrLeft`, `StrRight`, `StrLeftBack`, `StrRightBack` | No equivalent |20| Run formula language | `Evaluate("@Formula")` | No equivalent |21| Include files | `%Include "filename"` | No equivalent |22| Module scope | `Option Public` (makes module members public) | `Public` on each member |23| Require declarations | `Option Declare` | `Option Explicit` |24| Object cleanup | `Delete` statement | `Set x = Nothing` |25| Print in web agents | Writes to **HTTP response** | Writes to console/debug |26| Property syntax | `Property Get/Set/Let` with no parentheses on Get | Parentheses on Get |27| No `Set` for assignment | `Set` only for object references | `Set` for objects, `Let` for values |28| String variant | Use `$` suffix: `Left$()`, `Mid$()` | No `$` variants |29| Class events | `Sub New` / `Sub Delete` | `Class_Initialize` / `Class_Terminate` |30| Error object | `Err`, `Erl`, `Error$` (line number tracking) | `Err.Number`, `Err.Description` |31| Boolean values | `True = -1`, `False = 0` | Same, but watch for implicit conversion |3233## Scope: Backend Classes Only3435This project uses Domino as a **web application server**. All code runs in agents and script libraries triggered by HTTP requests. **Never use front-end (UI) classes:**3637- **DO NOT USE:** `NotesUIWorkspace`, `NotesUIDocument`, `NotesUIView`, `NotesUIDatabase`38- **USE:** `NotesSession`, `NotesDatabase`, `NotesDocument`, `NotesView`, etc.3940## Web Agent Essentials4142```lotusscript43Sub Initialize44 Dim session As New NotesSession45 Dim db As NotesDatabase46 Dim doc As NotesDocument4748 Set db = session.CurrentDatabase49 Set doc = session.DocumentContext ' CGI variables and POST data5051 ' Read query string52 Dim queryString As String53 queryString = doc.GetItemValue("Query_String_Decoded")(0)5455 ' Output HTTP response56 Print "Content-Type: application/json"57 Print ""58 Print |{"status": "ok"}|59End Sub60```6162**Key web agent rules:**63- `Print` writes to the HTTP response body — first print `Content-Type`, then a blank line, then body64- `session.DocumentContext` provides CGI variables as fields on a document65- Pipe `|` characters delimit strings that can contain quotes66- Web agents run as the authenticated user (or Anonymous for unauthenticated)6768## Common Gotchas69701. **GetItemValue returns a Variant array** — always index with `(0)` for single values712. **Save is not automatic** — always call `doc.Save True, False` after modifications723. **Nothing checks** — always check `If Not (doc Is Nothing)` before using objects734. **String comparison** — use `StrCompare` or `LCase$()` for case-insensitive comparison745. **Arrays are 0-based by default** — use `Option Base 1` to change, or use `LBound`/`UBound`756. **Lists vs Arrays** — Lists are associative (keyed by string), Arrays are indexed by integer767. **Variant vs typed variables** — always use `Option Declare` and type your variables778. **RichText fields** — cannot be read with `GetItemValue`, must use `GetFirstItem` and cast to `NotesRichTextItem`789. **Date handling** — use `NotesDateTime` objects, not native date functions, for Domino date fields7910. **Chr(0) is CRLF** — in Domino, `Chr(0)` acts as `Chr(10)+Chr(13)` (newline), not a null byte as in standard ASCII. Long-standing Domino behavior since the 1990s.8011. **Large POST bodies are chunked** — Domino splits large `Request_Content` into numbered fields (`request_content_000`, `request_content_001`, etc.), each ~32-64K depending on platform8112. **NotesHTTPRequest.ResponseCode is a String** — returns the full status line (e.g., `"HTTP/1.1 200 OK"`), NOT an integer. Use `InStr(http.ResponseCode, "200") > 0` to check status — never `http.ResponseCode = 200`8283## Reference Files8485- **syntax-fundamentals.md** — Data types, control flow, error handling, strings, arrays, Lists86- **domino-object-model.md** — Backend class hierarchy and usage (NotesSession → NotesDocument)87- **domino-modern-features.md** — Domino 10-14: DQL, JSON classes, HTTPRequest, LS2J, MIME88- **web-agent-patterns.md** — Web agent patterns: CGI vars, JSON output, CRUD, error handling