You are developing an Appian application for employees to submit expense reimbursement requests. Users report that after clicking Submit, they sometimes receive an error saying the request was not saved. However, when they try again, they end up with two reimbursement requests in the system.
How would you investigate this issue, what do you think could be causing it, and how would you fix it?
Answer
First, I would reproduce the issue in a development environment to understand the exact conditions triggering it. My investigation would focus on three areas:
1. Interface Layer
- Check if the Submit button has a saveInto parameter that triggers multiple process starts
- Verify the button is not inside a RepeatingSectionLayout that could cause duplicate event firing
- Review whether the interface is using a!save() correctly and not executing multiple times
- Confirm there is no client-side retry logic running in the background
2. Process Model Layer
- Check process history to see if the process is being initiated more than once per submission
- Verify there are no parallel gateways accidentally creating duplicate write paths
- Review all Write to Data Store Entity smart services to ensure only one exists in the happy path
- Check if any error handling paths are also writing data before throwing the error
3. Data Layer
- Query the database to compare timestamps on duplicate records — if they are milliseconds apart, it confirms a double-click or double-submission issue
- Check if there is a unique constraint on the table that should prevent duplicates but is missing
Root Cause
The most likely cause is a race condition — the user clicks Submit, the process starts but takes time to complete, the user sees no feedback and clicks Submit again, creating a second process instance. The error message they see is likely from the first submission timing out on the UI side, even though the data was successfully written.
Fix Immediate: Disable the Submit button after the first click using a local variable:
- Process Model: Add a duplicate check at the start of the process using a Query Entity smart service to verify no existing request exists for the same employee and date range before writing
- Database: Add a unique constraint on relevant columns such as employee_id, submission_date, and amount to prevent duplicates at the data layer
- User Experience: Show a loading indicator or success message immediately after submission so users know their request is being processed and don't click again
This three-layer approach — UI, process, and database — ensures the issue is prevented at every level rather than relying on a single fix.