unbridled-41 opened a new issue, #4795:
URL: https://github.com/apache/rocketmq-dashboard/issues/4795
### Studio Version
Trunk `rocketmq-studio` @ `4c697f07` (line references are as of that commit).
### Problem
`AiRunService.sendMessage`
(`server/src/main/java/org/apache/rocketmq/studio/ops/ai/conversation/AiRunService.java:202`)
inserts the run row (status `QUEUED`) and **then** calls
`workspace.prepare(...)` at `AiRunService.java:207-208`, outside any try/catch.
`RmqctlWorkspace.prepare` (`agent/RmqctlWorkspace.java:221-227`) deliberately
throws `BusinessException` for three configuration conditions — an unusable
`rmqctl-server-url`, an unusable `workspace-dir`, or an instance whose
credential cannot be resolved (e.g. the bound instance was deleted, or its
admin/cloud credential removed after the conversation was created;
`InstanceCredentialResolver.resolveByName` throws 404/422).
When it throws, the SSE stream refuses with the error, but the
already-inserted run row is never registered, never finalized, and stays
`QUEUED`. Admission is one-active-run-per-conversation
(`findActiveByConversationId` at `AiRunService.java:191-195`), so **every
subsequent message for that conversation is refused 409 "answer in progress"**.
The only recovery is the orphan sweep in `purgeExpired` —
`@Scheduled(fixedDelayString =
"${studio.ai.conversation.cleanup-interval:PT24H}")` with a 10-minute
`orphanRunTimeout` grace — i.e. up to 24 hours, or a server restart.
### Evidence
1. `prepare()` javadoc promises "these fail loudly": `@throws
BusinessException when the workspace could be built but the configuration is
wrong: an unusable rmqctl-server-url, an unusable workspace-dir, or an instance
with no resolvable credential` (`RmqctlWorkspace.java:221-227`).
2. `insertRun` at `AiRunService.java:202` runs first; nothing between it and
the throw writes a terminal state. `registry.register` (`:217`) never runs, so
the row has no live handle and is invisible to the stop path's fast recovery.
3. Measured on trunk source in this sandbox: a test stubbing `prepare` to
throw 404 shows `sendMessage` propagating the exception with the row still
`QUEUED` and zero terminal updates — then, with the fix, the row reaches
`FAILED` before the exception is rethrown.
### Impact
A user whose conversation references a deleted or de-credentialed instance
cannot send any message for the rest of the day: every send returns 409 "busy"
while the conversation shows a stranded QUEUED run. The timeline never records
what happened, and the operator's only signal is a log line from the scheduled
sweep a day later.
### Expected behavior
An admission-time preparation failure must finalize the inserted row
(through the same exactly-once terminal path the stop of an owner-less run
uses) and still propagate the error to the caller.
### Related work
- #4754 (mine, merged): retention deleting conversation rows but not disk
workspaces — same subsystem, different lifecycle defect.
- #4685 (open): resuming a CLI session the provider lost — also
run-lifecycle, but about resume, not admission ordering.
- #4740 (open): refused send and the composer draft — the client side of the
same 409 refusal path.
## PR
Fix: #… (opened together with this issue).
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]