Skip to content

Anti-Patterns

Forgetting to Start a Session

The Problem

Calling a domain tool without a valid session_id:

WRONG:
slide(action: "add-blank", session_id: "made-up-id")  → success: false, "Unknown sessionId"

The Solution

Always start a session first and reuse the exact sessionId string it returns:

CORRECT:
result = presentation(action: "open", filePath: "C:\Decks\q4.pptx")
sessionId = result.sessionId
slide(action: "add-blank", session_id: sessionId)

Creating Then Re-Opening the Same File

The Problem

Treating presentation(action: "create", ...) like the old standalone create call and then opening the same file again:

WRONG:
presentation(action: "create", filePath: "C:\Decks\q4.pptx") → sessionId A
presentation(action: "open", filePath: "C:\Decks\q4.pptx")   → sessionId B

The Solution

create already returns a live session. Reuse it directly:

CORRECT:
result = presentation(action: "create", filePath: "C:\Decks\q4.pptx")
sessionId = result.sessionId
slide(action: "add-blank", session_id: sessionId)

Wrong Index Base (0-Based Instead of 1-Based)

The Problem

Treating slide_index/shape_index/table row/column as 0-based, matching most programming languages:

WRONG: assuming the first slide is index 0
shape(action: "get-count", session_id: ..., slide_index: 0)  → success: false (out of range)

The Solution

Every index in this tool surface is 1-based, matching PowerPoint's own object model:

CORRECT:
shape(action: "get-count", session_id: ..., slide_index: 1)  → the first slide

See behavioral-rules.md for the full indexing rule.

Forgetting to Save

The Problem

Making changes, then closing without saving:

WRONG:
slide(action: "add-blank", session_id: ...)
textframe(action: "set-text", session_id: ..., ...)
presentation(action: "close", sessionId: ...)   → changes since last save are LOST

The Solution

Close with save enabled when changes were made:

CORRECT:
slide(action: "add-blank", session_id: ...)
textframe(action: "set-text", session_id: ..., ...)
presentation(action: "close", sessionId: ..., save: true)

Expecting Close to Block

The Problem

Waiting for or polling after presentation(action: "close", ...), assuming it does not return until PowerPoint's process has fully exited:

WRONG:
presentation(action: "close", sessionId: ...)
presentation(action: "list")  → repeatedly poll, waiting for POWERPNT.exe to disappear from Task Manager

The Solution

Close returns as soon as the session is removed from the registry; PowerPoint's own process cleanup happens in the background afterward and can take up to a few minutes. The session is already gone from presentation(action: "list") immediately; do not wait on the OS process.

Skipping Visual Verification

The Problem

Trusting success: true from a shape/chart/table/image call as proof the slide looks right:

WRONG:
chart(action: "add-chart", session_id: ..., slide_index: ..., ...)  → success: true
presentation(action: "close", sessionId: ..., save: true)
## Never looked at the rendered slide — chart could be mis-sized, overlapping, or have wrong data

The Solution

Export and inspect the result before saving/closing when visual content was added or changed:

CORRECT:
chart(action: "add-chart", session_id: ..., slide_index: ..., ...)
export(action: "export-slide-to-image", session_id: ..., slide_index: ..., output_path: ...)
## Inspect the image, fix issues found
presentation(action: "close", sessionId: ..., save: true)

Delete-and-Rebuild for Small Changes

The Problem

Deleting and re-creating a shape/table/chart to make a small change:

WRONG: fixing one table cell
shape(action: "delete", session_id: ..., slide_index: ..., shape_index: ...)
table(action: "add-table", session_id: ..., slide_index: ..., rows: 4, columns: 3, ...)
## ... re-populate every cell from scratch ...

The Solution

Use the targeted update action for the specific thing that changed:

CORRECT:
table(action: "set-cell-text", session_id: ..., slide_index: ..., shape_index: ..., row: 3, column: 2, text: "$1.8M")

Same principle for shapes: prefer shape(action: "set-position", ...)/shape(action: "set-size", ...) over delete-and-recreate (see slides-and-shapes.md).

Session Leaks

The Problem

Opening several presentations and never closing them:

WRONG:
presentation(action: "open", filePath: "file1.pptx")  → session 1
presentation(action: "open", filePath: "file2.pptx")  → session 2
presentation(action: "open", filePath: "file3.pptx")  → session 3
## ... none ever closed

Each open session holds its own POWERPNT.exe process. Left unclosed, they accumulate, consume memory, and keep file locks on disk.

The Solution

Close each session when its work is done, saving first if changes were made:

CORRECT:
s1 = presentation(action: "open", filePath: "file1.pptx")
## ... work ...
presentation(action: "close", sessionId: s1, save: true)

s2 = presentation(action: "open", filePath: "file2.pptx")
## ... work ...
presentation(action: "close", sessionId: s2, save: true)

Assuming Multi-Series Charts in a Single Create Call

The Problem

Trying to pass multiple series into a single chart(action: "add-chart", ...) call when a more explicit series-management workflow is needed.

The Solution

Use chart(action: "add-chart", ...) for the initial chart, then chart(action: "add-series", ...) for additional series, or chart(action: "replace-chart-data", ...) when replacing the whole data set.

Guessing Layout Names

The Problem

Passing an invented or approximate layout_name to layout(action: "set-layout", ...) (for example, "Blank", "TitleSlide"):

WRONG:
layout(action: "set-layout", session_id: ..., slide_index: ..., layout_name: "TitleSlide")  → success: false

The Solution

Use the exact PpSlideLayout enum member name (ppLayoutTitle, ppLayoutBlank, etc.) — see layouts.md for the common ones.

Discovery Loop Without Action

The Problem

Repeating presentation(action: "list"), slide(action: "get-count", ...), or shape(action: "get-count", ...) multiple times without acting on the result.

The Solution

Call a discovery action once, then act on what it returned. If a session genuinely expired, reopen it once and continue — do not loop on the same discovery call more than twice in a row.