Troubleshooting Work Orders
When something looks wrong on the work order board, the cause is almost always one of the patterns below. Walk this list before opening a support ticket.
A task is stuck in Created and the rule should have created it
Three things to check:
- Is the rule enabled? Open
/dashboard/task-rulesand confirm the toggle is on. Disabled rules don't fire. - Did the cron actually run? Look at
task_rule_runsfor the rule's most recent entry. If it's older than the rule's schedule, the cron didn't fire — checkvercel.jsonfor the cron config and your Vercel deployments page for failures. - Did the rule match zero vehicles? Hit the Test button on the rule. If the dry-run returns zero matches, your trigger config is too narrow.
The vehicle did not flip to maintenance when I created a critical task
Two causes:
- Active ride — The auto-flip trigger refuses to interrupt a ride. If
vehicles.status = 'in_use', the flip waits for the ride to end. The task is still created; the vehicle just won't go tomaintenanceuntil ride close. - Priority is below
high— Onlyhighandcriticalpriorities trigger the flip. If you setmedium, the vehicle stays available.
A tech says they can't tap Start
The Start button is photo-gated. The tech must capture or attach a before photo first. If they're tapping in offline mode, the photo upload may be queued — they need to see the photo in the "Photos" section of the task detail before the button enables.
If they have a photo attached and the button is still gray, check:
- Are they the current assignee? If a manager re-assigned the task while the tech wasn't looking, only the new assignee can press Start.
- Is the task in
assignedstate? If it'screated(unassigned), the button is hidden.
A tech tried to Resolve and got "already closed by ___"
This is the offline-queue conflict resolution at work. The tech resolved the task offline, but the manager force-closed it server-side first. The client sees 409 on sync and shows the message. The tech's photos are still saved to the closed task (client-wins on photos and notes), so no evidence is lost.
Verify button is gray for a manager
Two reasons:
- Task is not in
resolvedstate — verify requires resolve first. The state machine refuses to skip. - Manager role is wrong — Only
ops_managerandlead_techcan verify. A regulartechorjunior_techcannot, even on their own work.
Duplicate tasks for the same vehicle
The system blocks duplicates of the same task_type, not across types. So a vehicle can have one open repair, one open battery_swap, and one open cleaning simultaneously. That's intentional.
If you're seeing duplicates of the same type, check:
- One is
verifiedbut notclosed—verifiedtasks are still considered closed for dedup purposes. If you're seeing both, refresh; one of them is on its way toclosed. - A rule fired before the existing task was loaded — race condition, very rare. Manually close the duplicate.
Tasks are not getting auto-assigned by proximity
assign_by_proximity reads users.last_lat and users.last_lng to pick the nearest tech. Two things to check:
- Are your techs sharing location? The operator-app posts to
/api/operator/locationevery few minutes when foregrounded. If a tech has location services off, they're invisible to proximity assignment. - Are the columns populated? Query
SELECT last_lat, last_lng, last_lat_at FROM users WHERE id IN (your tech IDs). Iflast_lat_atis older than an hour, that tech won't be picked.
The fallback when no tech is in range is to leave the task unassigned (Created column) for any tech to claim.
A vendor isn't getting the magic link email
Three things to check:
- Email delivery — Magic-link emails go through Resend. Check the Resend dashboard for delivery status and bounce notices.
- Vendor row missing email —
vendors.contact_emailis the destination. If it's NULL, no email is sent. - Token already used — Magic links are 7-day, single-task tokens. If the vendor already accepted, the link is no longer "new" — they should bookmark the URL after first open.
Photos won't upload from the operator-app
Photos cache locally first at ${FileSystem.documentDirectory}task-photos/<task_id>/ and upload on reconnect. If a tech reports that photos are "stuck":
- Check the upload progress bar on the task detail screen
- Force a sync from Settings → Sync Pending Items in the operator-app
- If that fails, check the device's Supabase Storage permissions — the
task-photosbucket requires authenticated upload
The fallback is to text the photos to the ops manager who can attach them from the dashboard.
"Cannot create task — duplicate" error from the API
The /api/tasks POST returns 200 with skipped_duplicate: true when a same-type open task exists. This is a feature, not a bug. To create a second task against the same vehicle:
- Close the first task, or
- Use a different
task_type, or - Wait until the first is
verified(which counts as closed for dedup)
SLA breach notifications are too noisy
Three knobs:
- Loosen low/medium SLAs — if
lowis set to 24h and you have 200 low-priority tasks, you're going to breach a lot. The defaults are 7 days forlow, 72h formedium. - Turn off Slack on low-priority rules — set
action_config.notify_slack: falseon rules that don't deserve Slack. - Wait for batching — Expo push batches breaches into digests at 5-in-10-minutes. Slack doesn't batch.
When to escalate to support
If a task or rule looks broken and none of the above applies, file a ticket through your CSM with the task ID and the timestamp. We can pull the task_rule_runs audit and the relevant cron logs.