{"record":{"id":"05e68250e4e1ec69","repo":"RocketChat/Rocket.Chat","slug":"old-url-format","errorCode":"old-url-format","errorMessage":"Old Url Format","messagePattern":"Old Url Format","errorType":"exception","errorClass":"OldUrlRoomError","httpStatus":null,"severity":"info","filePath":"apps/meteor/client/views/room/hooks/useOpenRoom.ts","lineNumber":105,"sourceCode":"\t\t\t\t}\n\n\t\t\t\tif (errorCode !== 'error-invalid-room') {\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\n\t\t\t\tif (type !== 'd') {\n\t\t\t\t\tthrow new RoomNotFoundError(undefined, { type, reference });\n\t\t\t\t}\n\n\t\t\t\ttry {\n\t\t\t\t\tconst { room } = await createDirectMessage({ usernames: reference });\n\n\t\t\t\t\tdirectRoute.push({ rid: room._id }, (prev) => prev);\n\t\t\t\t} catch (error) {\n\t\t\t\t\tthrow new RoomNotFoundError(undefined, { type, reference });\n\t\t\t\t}\n\n\t\t\t\tthrow new OldUrlRoomError(undefined, { type, reference });\n\t\t\t}\n\n\t\t\tif (!roomData._id) {\n\t\t\t\tthrow new RoomNotFoundError(undefined, { type, reference });\n\t\t\t}\n\n\t\t\tconst unsetKeys = getObjectKeys(roomData).filter((key) => !(key in roomFields));\n\t\t\tunsetKeys.forEach((key) => {\n\t\t\t\tdelete roomData[key];\n\t\t\t});\n\t\t\tRooms.state.store(roomData);\n\n\t\t\tconst room = Rooms.state.get(roomData._id);\n\n\t\t\tif (!room) {\n\t\t\t\tthrow new TypeError('room is undefined');\n\t\t\t}\n","sourceCodeStart":87,"sourceCodeEnd":123,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/f9d3ec372bb580fa8d036f94cf03925a478ef768/apps/meteor/client/views/room/hooks/useOpenRoom.ts#L87-L123","documentation":"Thrown as OldUrlRoomError ('old-url-format') right after successfully creating a DM and pushing the new rid onto the direct route. It is a control-flow signal, not a real failure: it aborts the current queryFn so the OldUrlRoomError is caught by react-query's retry logic (which disables retries) and triggers a re-render against the newly pushed rid route.","triggerScenarios":"Opening a /direct/username URL where the DM didn't exist; im.create succeeds, direct route is pushed with the real rid, and this error halts the now-stale query against the username-based reference.","commonSituations":"Normal flow whenever a legacy username-based DM URL is opened for the first time; not a bug — it is the mechanism that forces the route to switch to the rid-based URL.","solutions":["Do not 'fix' this throw — it is intentional. Ensure downstream error UI treats OldUrlRoomError as a redirect signal, not a user-facing error.","If the error leaks to the UI, verify the retry function lists OldUrlRoomError as unrecoverable and that the route change triggers a fresh query.","Keep directRoute.push before the throw so the new rid URL is in place when the query re-runs."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":"const isOldUrlRedirect = (e: unknown): boolean => e instanceof OldUrlRoomError;","tryCatchPattern":"// Treat OldUrlRoomError as a silent redirect, not a user-facing error.\nif (error instanceof OldUrlRoomError) {\n  // route push already happened; just suppress the error UI\n  return null;\n}","preventionTips":["Never render an error toast for OldUrlRoomError; it is a redirect signal.","Keep directRoute.push before the throw.","Ensure retry disables for OldUrlRoomError (already configured)."],"tags":["client","direct-message","routing","control-flow"],"backgroundTag":null,"analyzedSha":"f9d3ec372bb580fa8d036f94cf03925a478ef768","analyzedAt":"2026-08-12T19:07:17.372Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}