# Reviewing Uipath Code

> Use when analyzing UiPath workflows for bugs, anti-patterns, data validation issues, error handling gaps, and security vulnerabilities before deployment

- Skill: `kranjata03/reviewing-uipath-code` (Agent Skill)
- Install (CLI): `npx skillmds@latest add kranjata03/reviewing-uipath-code`
- Raw SKILL.md: https://api.skillmd.com/api/skills/kranjata03/reviewing-uipath-code/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Security
- Author: Kranjata03 (https://skillmd.com/u/kranjata03)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/kranjata03/reviewing-uipath-code

---


# Reviewing UiPath Code

## Overview

UiPath workflows have unique failure modes: data extraction fragility, asset-retrieval nulls, email/notification gotchas, and silent failures in exception handlers. This skill identifies real bugs—not style—by focusing on failure paths and data flow integrity.

## Core Anti-Patterns to Hunt

### 1. Send Email Gotchas

| Bug | Symptom | Fix |
|-----|---------|-----|
| `SaveAsDraft="True"` | Emails stuck in drafts, never sent | Set `SaveAsDraft="False"` or use `Send()` activity |
| No recipient validation | Invalid emails cause transaction failures | Add email format regex check before sending |
| Asset retrieval not null-checked | Crash if Asset is empty/null | Add guard: `If(Not String.IsNullOrEmpty(assetValue))` |
| Asset split without trim | Extra spaces break email parsing | Use `.Split(...).Select(e => e.Trim())` |
| No retry on transient errors | One SMTP timeout fails entire batch | Wrap in Try/Catch with 3x retry logic |

**Example fix pattern:**
```xaml
<!-- BEFORE (broken) -->
<ui:GetRobotAsset AssetName="Mails"> [mails] </ui:GetRobotAsset>
<Assign> [mailsArray = mails.Split(New Char() {","c})] </Assign>

<!-- AFTER (safe) -->
<If Condition="[Not String.IsNullOrEmpty(mails)]">
  <Assign> [mailsArray = mails.Split(...).Where(Function(e) IsValidEmail(e)).ToArray()] </Assign>
  <!-- handle empty case -->
</If>
```

### 2. Data Extraction Brittleness

| Bug | Symptom | Fix |
|-----|---------|-----|
| No extraction failure check | Process continues with null fields | Validate each extracted field is not empty |
| Hardcoded field positions | Layout change breaks extraction | Use anchor-based or CV-based extraction |
| Missing fields cause downstream crash | SharePoint upload fails silently | Default missing fields to "N/A" or skip record |
| Multiple identical actions | Redundant clicks slow process, add failures | Consolidate to single action; check logs |
| No rollback on partial extraction | Half-complete records in SharePoint | Extract all → validate all → then store |

**Pattern to verify:**
- Each `NGetText`/`NGetOCR` has a following validation activity
- Missing fields handled explicitly (not just passed as null)
- Extraction wrapped in Try/Catch with field-specific logging

### 3. Orchestrator Asset Risks

| Bug | Symptom | Fix |
|-----|---------|-----|
| Asset path wrong or folder removed | `GetRobotAsset` silently returns empty | Verify Asset path exists before workflow runs |
| No asset existence check | Crashes only in prod (not dev) | Use Try/Catch around GetRobotAsset, log failure |
| Sensitive values (passwords, keys) | Logged in plaintext | Never log asset values; mask in output |
| Stale asset pulled at runtime | Configuration change doesn't take effect | Don't cache asset; re-fetch per transaction |

### 4. Exception Handling Gaps

| Bug | Symptom | Fix |
|-----|---------|-----|
| Empty catch blocks | Exception silently swallowed, no trace | Log exception message + stack trace in every Catch |
| Catch too broad (catches `Exception`) | Business errors treated as system errors | Catch `BusinessRuleException` separately from `Exception` |
| Finally block has no cleanup | Resources leak (connections, files, windows) | Explicit cleanup: close browser, release locks |
| No transaction status update on error | Queue item never marked failed | Set status (Success/BusinessException/SystemException) in all paths |

### 5. Logging Deficiencies

| Bug | Symptom | Fix |
|-----|---------|-----|
| No log of extracted values | Can't debug extraction failures | Log each extracted field immediately after extraction |
| No log of email recipients | Can't audit who got notified | Log recipient, subject, send timestamp |
| Exception log missing context | Stack trace alone doesn't point to cause | Include: TransactionID, input values, current state |
| No timing log | Performance bottlenecks invisible | Log start/end time for slow activities (web scrape, AI call) |

## Audit Checklist

### Email/Notification Flow
- [ ] Email recipient validated before send (format check, not empty)
- [ ] Recipient fetched from approved Orchestrator Asset, not hardcoded
- [ ] Recipient list trimmed/deduplicated
- [ ] SendMailConnections: `SaveAsDraft="False"` (or equivalent send)
- [ ] Retry logic for transient mail failures
- [ ] Log: recipient, subject, success/failure, timestamp
- [ ] Email body includes relevant transaction data (not generic)
- [ ] Condition for sending is explicit and logged (not implicit)

### Data Extraction
- [ ] Each extracted field logged immediately after NGetText/NGetOCR
- [ ] Null/empty fields handled: either reject, default, or skip
- [ ] Extraction failures wrapped in Try/Catch
- [ ] No hardcoded field positions; use anchors/CV/selectors
- [ ] Validation logic before downstream activities (upload, send)
- [ ] Extraction order matches expected data flow (don't extract out of order)

### Orchestrator Integration
- [ ] All GetRobotAsset calls guarded by null check
- [ ] Asset paths logged at start for debugging
- [ ] Config values used (not hardcoded URLs, paths, recipients)
- [ ] No sensitive data in logs

### Exception Handling
- [ ] No empty Catch blocks
- [ ] Business exceptions (`BusinessRuleException`) handled separately
- [ ] System exceptions logged with full context: TransactionID, input, state
- [ ] Transaction status updated in all paths (Success/BRE/System)
- [ ] Finally block has cleanup code (if needed)

### Logging & Audit Trail
- [ ] Transaction start logged with ID
- [ ] Each major step logged (extract → validate → store)
- [ ] Extracted values logged (not sensitive ones)
- [ ] Email sent/failed logged per recipient
- [ ] Any error includes: error message, source, transaction ID

## Common Mistakes

| Mistake | Why It Breaks | Example |
|---------|---------------|---------|
| "This email validation is too strict, skip it to save time" | One invalid email stops all notifications | Validate every recipient, log failures per-email |
| "We'll retry emails offline" | Never happens; broken emails stay broken | Retry logic must be inline |
| "Empty fields are fine, downstream will handle it" | Downstream crashes or produces garbage records | Validate at extraction time |
| "Logs clutter the output, let errors speak for themselves" | Errors are silent; untraceable in prod | Log everything; filter output locally, not in code |
| "SaveAsDraft is fine for testing" | Forgotten before deploy; emails never reach users | Always deploy with SaveAsDraft=False |

## Red Flags — Stop and Review

- [ ] Any `SaveAsDraft="True"` in email activities
- [ ] Email recipient list not validated/trimmed
- [ ] `GetRobotAsset` result used without null check
- [ ] Extract field, don't check if null, use downstream
- [ ] Catch block with no LogMessage
- [ ] Identical Click activities in sequence (redundant)
- [ ] Email body is generic/hardcoded (doesn't include order data)
- [ ] No retry logic on Mail Send activity
- [ ] Asset path hardcoded (should be in Config)
- [ ] No TransactionID in error logs

## Implementation Pattern

**For each activity that touches external systems:**

1. **Try** — Invoke activity (send email, extract data, upload file)
2. **Catch BusinessRuleException** — Log, set status, continue
3. **Catch SystemException** — Log with context, retry or end
4. **Catch generic Exception** — Treat as system error (shouldn't happen)
5. **Finally** — Cleanup (close connections, etc.)

**For each extracted field:**

```xaml
<NGetText> [fieldValue] </NGetText>
<ui:LogMessage Message="[&quot;Extracted [fieldName]: &quot; + fieldValue]" />
<If Condition="[String.IsNullOrEmpty(fieldValue)]">
  <!-- Handle missing: throw BRE, default, or skip -->
</If>
```

## Real-World Impact

A single forgotten `SaveAsDraft="True"` or missing email validation can:
- Block all notifications in production
- Leave stakeholders unaware of high-priority opportunities
- Mask extraction failures (silently create incomplete records)
- Create audit/compliance gaps (no record of who was notified)

Testing email workflows end-to-end catches these. Spot-checking code before merge prevents them entirely.

