ea42e955e4
Unify slot ownership: processKey() owns the slot until task.concurrencyKey is set. Previously, startTask() released the slot on errors (session.create catch, createResult.error), but processKey() catch block didn't release, causing slot leaks when errors occurred between acquire() and task.concurrencyKey assignment. Changes: - Remove all pre-transfer release() calls in startTask() - Add conditional release in processKey() catch: only if task.concurrencyKey not set - Add validation for createResult.data?.id to catch malformed API responses This fixes 'Task failed to start within timeout' errors caused by exhausted concurrency slots that were never released.