This page is for anyone facing an RPA developer round, from a first automation job to a lead role. Most UiPath interviews open with what RPA is and when it is the wrong tool, then test the platform: Studio, robots and Orchestrator. After that come workflow types, the REFramework, selectors, business and system exceptions, and queues. Many rounds add an Excel or email bot and ask how you keep credentials safe. Senior rounds bring a production failure and a judgement call. Each question shows what the interviewer is really checking, the shape of a strong answer and a short answer you can say out loud.
Search all questions by round, difficulty and level, or save the ones you want to practise.
Definition: software robots that repeat rule-based work by using applications the way a person does.
Contrast: traditional automation talks to systems directly through APIs, databases or code changes.
Trade-off: RPA is quick to build and needs no change to the target system, but it breaks more easily when screens change.
"RPA means robotic process automation. A software robot does rule-based work the way a person would: it opens applications, clicks, types, reads values off the screen, copies data between systems and sends emails. Traditional automation works underneath the screen. A developer connects systems through APIs or the database, or changes the application itself. The big advantage of RPA is that it sits on top of what you already have, so you can automate a process across an old desktop app and a web portal without touching either one, and it's quick to deliver. The cost is that it depends on the screens. If a button moves or a login page changes, the robot can fail, so RPA needs good error handling and someone watching it."
Describing RPA as physical robots or as AI that makes its own decisions, rather than rule-based work through the user interface.
Better options exist: a stable API, a built-in system feature or an integration tool does the job more reliably.
Wrong kind of work: judgement calls, messy unstructured input, or very low volume that never pays back the build.
Unstable ground: screens that change often, a system about to be replaced, or a broken process that should be fixed first.
"I'd push back in a few situations. First, if the system has a reliable API or a built-in feature that does the job, an integration is sturdier than a robot clicking through screens. Second, if the work needs judgement, like deciding whether a customer complaint is fair, or the input is messy handwriting and free text, rules alone won't cover it. Third, if the volume is tiny, say a task done twice a month in ten minutes, the build and support cost never pays back. And fourth, if the application is being replaced in a few months or its screens change every release, the bot will spend its life broken. I'd also say no to automating a process that's already broken. A robot just makes the same mistakes faster, so fix the process first."
Saying every repetitive task should be automated, or never mentioning APIs and process fixes as alternatives.
Fit: rule-based, digital and structured input, few exception paths, stable applications.
Value: volume, time per case, error cost, and how often the work runs.
Effort and risk: number of applications, remote desktops, access and compliance, and who owns the process.
Output: a documented process, a clear go or no-go, and the happy path plus known exceptions.
"I start by sitting with the person who does the work and watching a few real cases, because the written procedure is rarely the full story. I check fit: are the rules clear, is the input digital and structured, and how many exceptions are there? Then value: how many cases a day, how long each takes, and what an error costs. Then effort and risk: how many applications, whether any run over a remote desktop, whether the robot can get its own login, and whether there are audit or data rules. I put this into a simple score so candidates can be compared fairly. If it passes, I write up the process with the happy path and every known exception, and I get the process owner to sign it off before any build starts."
Jumping straight into building from a verbal description without watching the process or agreeing the exceptions.
Request: what they asked for and why they wanted it.
Concern: the evidence that the bot would fail or not pay back.
Alternative: what you proposed instead and how you presented it.
Result: what was decided and what happened next.
"At my last company, the operations team wanted a bot to copy order updates from our CRM into the warehouse system every hour. When I looked at it, both systems had APIs, and the warehouse system was already sending some data back through an integration. A robot would have meant two logins, screen scraping and a bot that broke with every CRM release. I showed the process owner a short comparison: the bot's build time and the support it would need, against a small extension of the existing integration. I was careful not to make it sound like a refusal, and I offered to automate a different manual task for the same team that really did need a bot. They agreed. The integration went live within a few weeks, and the bot we built instead is still running."
A story where you simply refused, or one where you built something you knew was a bad idea and said nothing.
Surface it: show the manager the new cases, with how often each occurs.
Scope: go live with the well-understood cases; send the rest to people as business exceptions.
Protect: clear exception messages, a daily report, and a short hypercare period.
Follow up: document each new case and add it in a later release.
"I'd go to the manager early, not on Thursday night, with a short list of the new cases, how often each shows up in the test data, and what the bot would do with them today. Then I'd offer a way to keep Friday. The bot goes live on the cases we fully understand, and anything that doesn't match the known rules is thrown as a business exception with a clear reason, so a person handles it instead of the bot guessing. I'd set up a daily summary of those exceptions and stay close to it in the first weeks. Meanwhile I'd get the process owner to confirm the rules for each new case and add them in the next release. That way the business gets value on the date, and nothing risky is automated on assumptions."
Guessing the rules for the unknown cases to hit the date, or telling the manager only on the day it's due.
Studio: where developers design, debug and publish workflows.
Robot: the runtime that executes a published process on a machine.
Orchestrator: the web-based control centre for deploying, scheduling, queues, assets and logs.
"Studio is the design tool. I build workflows there by dragging activities, set up variables and arguments, and debug step by step. When it's ready I publish it, which packages the project and sends it to Orchestrator. The Robot is the part that actually runs the process on a machine. It's the one clicking, typing and reading screens. Orchestrator is the web-based control centre that ties it together. From there you deploy packages as processes, start or schedule jobs, trigger jobs when queue items arrive, store assets like settings and credentials, manage queues and machines, and read the logs every robot sends back. So in short, Studio builds it, Orchestrator manages and schedules it, and the Robot runs it."
Thinking Orchestrator runs the automation itself, or not knowing how a workflow gets from Studio to a robot.
Attended: runs on a person's own machine, in their session, usually started by them.
Unattended: runs on its own machine or virtual machine, started by Orchestrator with no one watching.
Choice: attended for help at the desk mid-task; unattended for end-to-end back-office volume.
"An attended robot works alongside a person. It runs on their own computer, in their logged-in session, and they usually start it themselves from UiPath Assistant when they need help, like a call centre agent who clicks a button and the bot pulls a customer's details from three systems while they stay on the call. An unattended robot runs on its own, on a dedicated machine or virtual machine. Orchestrator starts it on a schedule or when queue items arrive, and it logs into Windows with its own account. I'd pick attended when a human needs to stay in the loop or the task sits in the middle of their work. I'd pick unattended for high-volume back-office work that can run end to end, often overnight, without anyone watching."
Saying the only difference is licensing, or suggesting an attended robot for overnight batch work with no one at the machine.
Sequence: straight-line steps that run one after another, like logging in or filling a form.
Flowchart: branching and loops back, several decision points in one view.
State machine: a process that moves between defined states on conditions, like the REFramework.
"I use a sequence for straight-line steps with little branching: open the app, log in, type values, click save. It's simple and most small reusable workflows are sequences. I use a flowchart when the logic branches a lot, with several decisions and paths that loop back, because you can see the whole picture on one canvas instead of nesting If activities five deep. A state machine is for a process that moves between a fixed set of states, where transitions decide what happens next. The REFramework is the best-known example: it goes from initialisation to getting a transaction, to processing it, and back again, until there's no more data and it moves to the end state. Often I combine them, with a state machine or flowchart at the top and sequences inside."
Saying they're interchangeable, or building one huge sequence with everything nested inside it.
Variables: hold data inside one workflow, limited to the scope where they're declared.
Arguments: pass data into and out of a workflow, with a direction of In, Out or In/Out.
Invoke: Invoke Workflow File maps the caller's variables to the child's arguments.
"A variable lives inside one workflow and only inside the scope where I declare it, so a variable made inside a sequence can't be seen outside it. An argument is how a workflow talks to the outside. It has a direction: In brings a value in, Out sends a result back, and In/Out does both. That matters when I break a big process into small workflows, like Login, ReadInvoice and PostInvoice. In the main workflow I use Invoke Workflow File, import the child's arguments and map them to my variables. Each piece can then be tested on its own and reused. I also name them clearly, like in_InvoiceNumber and out_Status, so anyone reading the invoke panel knows which way the data flows."
Using global-scope variables everywhere, or not knowing that arguments have a direction.
Initialization: read the config, fetch assets, open and log in to the applications.
Get Transaction Data: fetch the next item, often from a queue; if there's none left, go to the end.
Process Transaction: do the work for one item, then set its status: success, business exception or system exception.
End Process: close the applications cleanly and finish.
"The REFramework is a state machine template for transactional processes. In Initialization it reads the config file into a dictionary, pulls the named assets from Orchestrator, and opens and logs into the applications. Then Get Transaction Data fetches the next item. With queues, that's Get Transaction Item. It also checks whether someone asked the job to stop from Orchestrator. If there's no more data, it moves to End Process. Otherwise it goes to Process Transaction, where my own business logic runs for that one item. After that, the framework sets the transaction status. A success or a business exception moves straight to the next item. A system exception goes back to Initialization to restart the applications first. End Process closes everything down cleanly. The value is that logging, retries and recovery are already built in, so I only write the process part."
Only naming the states without saying how business and system exceptions lead to different transitions.
Settings sheet: process values like the queue name, folder paths, email addresses.
Constants sheet: technical values like retry counts, timeouts, standard messages.
Assets sheet: only the names of Orchestrator assets to fetch at run time.
Never: passwords or anything that changes per environment and belongs in Orchestrator.
"The Config file is an Excel workbook that the framework reads into a Config dictionary during Initialization. It has three sheets. Settings holds process values like the queue name, input folders and report recipients. Constants holds technical values like the maximum retries or timeouts, which rarely change. The Assets sheet doesn't hold values at all, just the names of Orchestrator assets. The framework looks each one up at run time and stores the result in the same dictionary. What should never go in there is a password or any secret, because that file ships inside the package and anyone with access can read it. Credentials live as credential assets in Orchestrator. I also move anything that differs between test and production into assets, so I can promote the same package without editing and republishing it."
Storing passwords in the Config file or hard-coding paths and URLs inside the workflows.
Record: the error is logged with a screenshot and the transaction status is set as a system failure.
Recover: applications are closed, killed if needed, and Initialization reopens them.
Retry: with queues, Orchestrator's auto retry creates a new copy of the item; without queues, the framework's MaxRetryNumber repeats the same transaction.
Safety: a limit on consecutive system exceptions stops a job that keeps failing.
"When Process Transaction throws anything that isn't a business rule exception, the framework treats it as a system exception. SetTransactionStatus logs the error, takes a screenshot and marks the item as failed with an application exception. Then it runs CloseAllApplications, and if that fails, KillAllProcesses, and moves back to Initialization so the applications are opened fresh. For retries, it depends on the source. With a queue, I set MaxRetryNumber in the config to zero and let the queue's own retry setting handle it: Orchestrator marks the failed item as retried and adds a new copy that the robot picks up again. Without a queue, MaxRetryNumber controls how many times the framework repeats the same transaction itself. There's also a consecutive system exceptions setting, off when it's zero, that stops the job rather than looping when an application is completely down."
Saying business exceptions are retried too, or not knowing the difference between queue retries and the framework's own retry counter.
What it is: an XML-like address made of tags and attributes that points to one UI element.
Reliable: stable attributes such as an automation id, a name or a fixed label.
Fragile: positions like idx, changing window titles, dates or record numbers baked in.
"A selector is how the robot finds a UI element. It's a small XML-like string: a chain of tags from the window or browser tab down to the element, each with attributes like app, title, name, id or aaname. When I indicate a button in Studio, it generates one, and I can refine it in UI Explorer. A reliable selector uses attributes that don't change between runs or machines, like an automation id or the button's label. A fragile one depends on things that move: the idx attribute, which is just the element's position among similar ones, a window title that includes today's date or a customer name, or a long chain of anonymous containers. Whenever I see idx or a changing title, I try to replace it with a stable attribute or a wildcard."
Accepting whatever Studio generates without checking it, or not knowing what idx means.
Full: includes the top-level window or browser tag, so the activity finds everything on its own.
Partial: leaves out the top-level part because a container already holds it.
Containers: Attach Window, Attach Browser, or Use Application/Browser in modern design.
"A full selector includes the whole path, starting from the top-level window or browser tab, so the activity can find its element with no help. That's what you get when an activity runs on its own, outside any container. A partial selector leaves out the top-level window part. It's used inside a container like Attach Window, Attach Browser, or in the modern design, Use Application/Browser. The container finds the window once, and every activity inside only needs the path within that window. Partial selectors are my default for anything with several steps on one screen. They're faster because the window isn't searched for again at every click, and easier to maintain, because if the window title changes I fix it in one place, on the container, not in twenty activities."
Mixing up the two, or saying a partial selector is simply an incomplete one.
Wildcards: an asterisk replaces zero or more characters, a question mark exactly one.
Variables: put a variable into an attribute so the selector targets the current record.
Check: test with several values and confirm it matches only one element.
"There are two tools. Wildcards handle parts I don't care about: an asterisk replaces any number of characters, and a question mark replaces exactly one. So a window title like Invoice 4471 - Portal becomes Invoice * - Portal. Variables handle the part that should change per record. In the selector editor I can put a variable into an attribute, so the selector points at the cell whose text equals the current invoice number. In older projects you do the same by building the selector as a string. Then I test it with a few different invoice numbers in UI Explorer to make sure it finds exactly one element each time, and that it fails cleanly when the invoice isn't on the screen."
<html app='chrome.exe' title='Invoice * - Portal' />
<webctrl tag='A' aaname='{{invoiceNumber}}' />
Hard-coding one invoice number, or using an asterisk everywhere so the selector matches the wrong element.
Why it's hard: the robot sees only a picture of the remote screen, not its UI elements.
Best option: install the remote runtime so real selectors work, or run the robot inside the remote environment.
Fallback: image, OCR and computer vision with anchors, keyboard shortcuts, and checks after every step.
"Over a Citrix or remote desktop session, the local robot only sees a streamed image, so normal selectors don't reach the buttons inside. My first choice is to get real selectors back. UiPath has a remote runtime component that's installed on the remote server, with an extension on the robot's side, and then selectors work almost like a local app. Another option is to put the robot itself inside the remote environment. If neither is allowed, I fall back to surface automation: computer vision, image matching and OCR, always anchored to a stable label rather than screen coordinates, and keyboard shortcuts wherever the app supports them. Those bots are slower and more fragile, so I add a wait for the expected screen after every step, and I agree a different support expectation with the business."
Going straight to clicking fixed coordinates, or not knowing that remote sessions need special handling at all.
Contain: stop wasteful retries, tell the business, agree a manual fallback for urgent items.
Fix: compare the new selector in UI Explorer, use stable attributes, test on the updated app.
Release: publish a new version, update the process, run a small batch first.
Prevent: get notice of app releases, keep selectors in one place, add a check after risky steps.
"First I'd stop the job or trigger so it isn't burning retries, and tell the process owner what's happening and when I expect a fix. If some items can't wait, I'd agree which ones the team handles by hand today. Then I'd open the updated app with UI Explorer and compare the old selector with what's there now. Usually an id or a label changed. I'd rebuild it on the most stable attributes I can find and test it against the new version, ideally in a test environment, not only on my machine. Then I'd publish a new version, update the process in Orchestrator and run a small batch before letting the full queue go. Afterwards I'd ask the application team to warn us about releases, and I'd make sure selectors live in one place so the next change is quicker to fix."
Editing and republishing straight to production with no test, or leaving the business uninformed until it's fixed.
Business exception: the data breaks a rule, like a missing PO number; the developer throws a BusinessRuleException.
System exception: something technical failed, like a timeout, a missing element or an app crash.
Handling: business exceptions go to a person with a clear reason; system exceptions are retried after a recovery.
"A business exception means the process can't continue because the data breaks a business rule. For example, the invoice has no purchase order number, or the amount is above the approval limit. The application is working fine, so retrying won't help. I check for these rules myself and throw a BusinessRuleException with a clear message, and the item goes to a person to fix. A system exception is a technical failure: an element wasn't found, the page timed out, or the app crashed. The data might be perfectly fine, so a retry after restarting the application often works. The REFramework treats them exactly that way. Queues do too: auto retry only applies to application exceptions. The message for a business exception should tell the business user what to do, not show a stack trace."
Retrying business exceptions, or letting every error surface as a generic system exception.
Try Catch: handle a specific error where it happens; most specific exception first; Finally for cleanup.
Retry Scope: repeat an action until a condition confirms it worked, for flaky steps.
Global Exception Handler: one per project, a last line for errors nothing else caught.
"Try Catch is for errors I can do something about at that point. I catch the most specific exception first, like a selector not found, then a general one, and use Finally for cleanup such as closing a file. Retry Scope is for steps that sometimes fail for no real reason, like a slow page. It runs the action, then checks a condition, for example that the confirmation message appeared, and repeats a set number of times if it didn't. The Global Exception Handler is a separate workflow, one per project, that catches anything nothing else handled, and it can log it, take a screenshot and decide to retry, ignore or abort. I rarely use it with the REFramework, because the framework already has a structured catch. What I avoid is Continue On Error set to true, because it hides real failures."
Wrapping the whole process in one Try Catch that swallows every error, or turning on Continue On Error everywhere.
Situation: what the bot did and how the failure showed up.
Investigation: logs, screenshots, queue items and reproducing it.
Fix: the immediate repair and the lasting change to design or monitoring.
Lesson: what you do differently on every bot since.
"At my last company I built an unattended bot that posted vendor invoices into a finance web portal. Two weeks after go-live, around a third of the items started failing each morning with a selector-not-found error. The screenshots showed a session-expired page. The job started early, and on busy mornings it took longer than the portal's session timeout, so the bot was sitting on an expired session. The quick fix was to check for the login page at the start of every transaction and log in again when needed. The lasting change was in how I build: I now add a check for the expected screen at the start of each transaction, and I set up an alert when failures in a run pass a threshold, so we hear about it before the business does."
Blaming the application team or the users and describing no change to your own design or monitoring.
Queue: a list of work items in Orchestrator; each item is one transaction with its own data.
Main path: New, then In Progress, then Successful or Failed.
Other statuses: Retried, Abandoned and Deleted; a postponed item simply stays New until its postpone date.
"A queue is a container in Orchestrator that holds work items. Each item is one transaction, like one invoice, with its data stored as fields called specific content, plus a reference, a priority and an optional deadline. When an item is added it's New. When a robot picks it up with Get Transaction Item, it becomes In Progress, and no other robot can take it. Then the robot sets it to Successful or Failed, and a failure is marked as either a business or an application exception. If auto retry is on and it was an application exception, the failed item is marked Retried and a fresh copy is added as New. An item left In Progress for about a day becomes Abandoned, and items can also be Deleted by hand. Postponing doesn't add a status: the item stays New and isn't handed out before its date. Every step is recorded, so queues give you an audit trail for free."
Thinking a queue is just a list the bot loops through, with no idea of item status or locking.
Dispatcher: reads the source, like an Excel file or mailbox, and adds one queue item per case.
Performer: takes one item at a time, processes it and sets its status, usually built on the REFramework.
Why: scaling across robots, clean retries per item, and reporting per transaction.
"The dispatcher is a small process that collects the work. It reads the source, say a daily Excel report or a mailbox, and adds one queue item per case with the data the performer will need. The performer is the process that does the work. It takes one item from the queue, processes it, and marks it successful or failed, usually on top of the REFramework. Splitting them has real benefits. If the performer crashes on item forty, the dispatcher doesn't need to run again, because the remaining items are still waiting. I can add more robots to the performer when volume grows, and each item gets its own retry and status. And the business gets reporting per transaction straight from the queue: how many were processed, how many failed and why."
Putting reading, looping and processing into one job so a single failure means starting over.
Design check: queue-based, one item per transaction, no shared state between items.
Scale out: several robots run the same performer; Orchestrator gives each item to only one robot.
Limits: application logins and licences, target system load, shared files and reports.
Measure: time per item first; sometimes the bot itself can get faster.
"First I check the design. If the performer works from a queue and each item is independent, scaling out is mostly setup: I add robots in the folder and let a queue trigger start more jobs as items pile up. Orchestrator locks an item once a robot takes it, so two robots never work the same one. Then I look for what else might break. Can the target application take two sessions with the same login, or does each robot need its own account? Will the system slow down under more load? Is there a shared Excel output that two robots would write to at once? I'd switch that to a report built from the queue at the end. And before buying robots I measure time per item, because removing fixed delays and using faster input methods sometimes gets you most of the gain."
Just adding robots without checking for shared state, licence limits or duplicate processing.
Contain: pause the process, alert finance so the payment can be stopped or recovered.
Scope: use queue items and logs to find every affected case, not just the one reported.
Root cause: usually a retry after the payment was already submitted, or the same item added twice.
Prevent: unique references on the queue, a check in the system before paying, no blind retry after the commit step.
"First I'd pause the process and disable its trigger, then tell finance straight away, because stopping or recovering the payment matters more than my investigation. Then I'd check the scope using the queue items and logs, and search for any other invoice with more than one payment, not just the one reported. For the cause, there are two usual suspects. Either the dispatcher added the invoice twice, or the payment went through and then a system exception hit, like a timeout on the confirmation screen, so the item was retried and paid again. To prevent it, I'd turn on unique references for the queue so the same invoice can't be added twice. In the performer, I'd check in the finance system whether the invoice is already paid before submitting. And any error after the submit step becomes a business exception for a person to check, not an automatic retry."
Quietly fixing the code without telling finance, or assuming it was a one-off without checking for other duplicates.
App-based: Excel Application Scope or Use Excel File open Excel itself; needed for macros, formatting, pivots.
Workbook: read and write the file directly without Excel installed; faster and simpler for plain data.
Habits: read once, work in a DataTable, write once; close Excel and handle locked files.
"The app-based activities, Excel Application Scope in classic projects or Use Excel File in modern ones, open Excel on the robot machine. I need those when the task depends on Excel itself: running a macro, refreshing a pivot, formatting cells or working with formulas. The workbook activities, like Read Range and Write Range under Workbook, read and write the file directly without Excel installed, so they're faster and work on robot machines that don't have Office. For plain data, that's my first choice. Either way I follow the same habit: read the whole range once into a DataTable, do the logic in memory, and write the result once, instead of reading and writing cell by cell. I also make sure Excel closes at the end, and I handle the file being locked because someone has it open."
Looping through thousands of cells with read and write activities inside Excel, or not knowing some activities need Excel installed.
Options: the Filter Data Table activity, DataTable.Select, or a LINQ expression in an Assign.
LINQ: filter the rows, then copy them into a new DataTable.
Edge case: copying zero rows throws, so handle the empty result.
"I wouldn't loop with For Each Row and an If. That works, but it's slow and clutters the workflow. For a simple condition, the Filter Data Table activity is fine and readable. For anything with conversions or several conditions, I use a LINQ query, either as an expression in an Assign or in an Invoke Code. I treat the table as an enumerable, keep the rows where status is Pending and the amount is above the limit, and copy the result into a new DataTable. The one trap is that CopyToDataTable throws an error if no rows match, so I check for any rows first and otherwise return an empty clone with the same columns. In a Visual Basic project it's the same idea with VB syntax. Afterwards I log the count, so the run log shows how many rows went forward."
// Invoke Code body; dtInput came from Read Range
var pending = dtInput.AsEnumerable()
.Where(r => r["Status"].ToString() == "Pending"
&& Convert.ToDecimal(r["Amount"]) > 1000m)
.ToList();
DataTable dtPending = pending.Any()
? pending.CopyToDataTable()
: dtInput.Clone(); // same columns, no rows
Not knowing that CopyToDataTable fails on an empty result, or looping and deleting rows from the same table you're iterating.
Connect: Outlook desktop activities, IMAP, or the Microsoft 365 or Gmail integration activities, depending on the setup.
Filter: only unread messages in the right folder, and only the attachment types you need.
Mark and move: mark read or move to a Processed folder so nothing is picked twice.
Hand off: add a queue item per invoice; send odd emails to an exceptions folder.
"First I'd find out how the robot can reach the mailbox. On a machine with Outlook, the Outlook activities can read a shared mailbox folder. Otherwise I'd use IMAP or the Microsoft 365 or Gmail activities, which work through an API connection. I'd read only unread messages from the invoice folder, with a sensible limit per run. For each message I save the attachments to a folder named by date and message, filtering to PDF files, and check the file isn't empty. Then the dispatcher adds one queue item per invoice with the sender, subject and file path. After that the message is moved to a Processed folder, so a rerun never picks it up again. Emails with no attachment or the wrong file type go to an exceptions folder, and someone gets a short summary."
Reading every email in the inbox each run with no way to mark what was done, so invoices are processed twice or skipped.
Store: a credential asset in Orchestrator, optionally backed by an external vault.
Fetch: Get Credential returns the username and a SecureString password.
Use: type it with a secure text property; never convert it to plain text or log it.
"Passwords never go in the workflow, the Config file or a text file on the machine. I create a credential asset in Orchestrator, and if the company uses a password vault, Orchestrator can be connected to that as the credential store. In the process, the Get Credential activity fetches it by name and returns the username as a string and the password as a SecureString. I pass that SecureString straight into the secure text property of the type activity, so the password never exists as plain text in the workflow. I never write it to a log, and I keep the asset name in the Config file, not the value. If each robot needs its own login, the asset can hold a different value per robot. And the bot account gets only the access it needs."
Keeping passwords in the Config file or a variable default, or logging them while debugging and forgetting to remove it.
Levels: Trace for detail, Info for milestones, Warn for odd but handled, Error and Fatal for failures.
Content: start and end, each transaction's reference and outcome, and the reason for any exception.
Never: passwords, full personal records or sensitive values.
"The Log Message activity has five levels: Trace, Info, Warn, Error and Fatal. I use Info for milestones anyone should see: process started, logged in, transaction started for invoice so-and-so, completed, and a summary at the end. Warn is for something unusual that the bot handled, like an empty input file. Error is for a failed transaction, with the reason in plain words, and Fatal is for something that stops the whole job. Trace is for step-level detail I only need while debugging. Logs go to Orchestrator, so support can filter by job or level, and I add custom fields like the transaction reference so they can search by invoice. What never goes in is a password or sensitive personal data like full account numbers, because logs are kept and read by many people."
Logging nothing but errors, or dumping whole data rows with personal details into the log.
Documentation: a short runbook with schedule, inputs, outputs and common errors with fixes.
Operability: settings in assets, clear log messages, business exceptions with plain reasons.
Transition: a hypercare period, shared on-call, then a clean handover.
"In my last role I handed a claims intake bot to our operations team after go-live. I wrote a two-page runbook: when it runs, where the input comes from, what it produces, and a table of the errors they'd see in Orchestrator with what each one means and what to do. I made sure every business exception had a message a non-developer could act on, like missing policy number, send back to the claims desk. Anything they might need to change, like the report recipients or the input folder, was an Orchestrator asset, so they never needed Studio. We did two weeks of hypercare where they watched the runs and I sat in on anything unusual. By the end they'd handled a few failures on their own, and they only called me for a real code change."
Saying the handover was just the code and a design document, with no runbook, clear errors or trial period.
ClapAssist is an AI interview assistant for Mac and Windows. It listens to the interview on your computer and shows you what to say, in short lines you can read while you talk. Your resume and notes are never stored on our servers. It stays out of screen share on every plan; only you can see it.