alibaba/spring-ai-alibaba · error · ResponseStatusException
Thread found but belongs to a different app/user.
Error message
Thread found but belongs to a different app/user.
What it means
findThreadOrThrow also throws 404 NOT_FOUND ('Thread found but belongs to a different app/user.') when a Thread record with the given threadId exists but its stored appName or userId differs from the path variables. Threads are namespaced by (appName, userId, threadId), so a match on ID alone is deliberately treated as not found to avoid cross-tenant leakage.
Source
Thrown at spring-ai-alibaba-studio/src/main/java/com/alibaba/cloud/ai/agent/studio/controller/ThreadController.java:99
HttpStatus.NOT_FOUND,
String.format(
"Thread not found: appName=%s, userId=%s, threadId=%s",
appName, userId, threadId));
}
Thread thread = optionalThread.get();
if (!Objects.equals(thread.appName(), appName) || !Objects.equals(thread.userId(), userId)) {
log.warn(
"Thread ID {} found but appName/userId mismatch (Expected: {}/{}, Found: {}/{}) -"
+ " Treating as not found.",
threadId,
appName,
userId,
thread.appName(),
thread.userId());
throw new ResponseStatusException(
HttpStatus.NOT_FOUND, "Thread found but belongs to a different app/user.");
}
log.debug("Found thread: {}", threadId);
return thread;
}
/**
* Retrieves a specific thread by its ID.
*
* @param appName The application name.
* @param userId The user ID.
* @param threadId The thread ID.
* @return The requested Thread object.
* @throws ResponseStatusException if the thread is not found.
*/
@GetMapping("/apps/{appName}/users/{userId}/threads/{threadId}")
public Thread getThread(
@PathVariable String appName, @PathVariable String userId, @PathVariable String threadId) {View on GitHub (pinned to f82da0b50f)
Solutions
- Use the exact appName and userId that were used when the thread was created
- Make client-generated thread IDs unique per user (append userId or use a UUID)
- List the user's threads (GET /apps/{appName}/users/{userId}/threads) to find the correct threadId
- Create a new thread under the correct (appName, userId) pair instead of reusing the ID
- Check for proxy/environment mixing that points the client at another deployment's data
Example fix
// before String threadId = "main-session"; // same for all users // after String threadId = userId + "-main-session"; // namespaced per user
Defensive patterns
Strategy: validation
Validate before calling
// ensure thread belongs to this user before fetching
String scopedId = userId + "-" + sessionId;
try { GET "/apps/{a}/users/{u}/threads/" + scopedId; } catch (NotFound e) { createThread(scopedId); } Try / catch
try { return getThread(app, user, id); } catch (HttpClientErrorException.NotFound e) { /* wrong owner or missing: create under this user */ return createThread(app, user, id); } Prevention
- Namespace client-generated thread IDs with userId
- Never share threadId values across users or deployments
- Store (appName, userId, threadId) together in client session state
- Verify multi-user routing does not mix studio instances
When it happens
Trigger: Requesting the same threadId under a different userId or appName than the one that created it; reusing a client-generated threadId (e.g. hardcoded or session-derived) across users; copy-pasting a URL between environments or accounts.
Common situations: Multi-user apps reusing the same session identifier for every user; load balancer routing to a different studio instance where another user created the same ID; tests hardcoding threadId while varying userId.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- Thread not found: appName=%s, userId=%s, threadId=%s
- Thread already exists:
- Failed to create thread
- Thread already exists:
- Failed to create thread (null result)
AI-assisted analysis of alibaba/spring-ai-alibaba@f82da0b50f (2026-09-09).
Data as JSON: /api/errors/8fe0745ed1c17459.
Report an issue: GitHub.