{"record":{"id":"8ca7f639a7f81dc5","repo":"overleaf/overleaf","slug":"user-id-not-valid","errorCode":null,"errorMessage":"user ID not valid","messagePattern":"user ID not valid","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"services/web/scripts/clear_sessions_set_must_reconfirm.mjs","lineNumber":30,"sourceCode":"  failedSet: [],\n  success: [],\n  printSummary: () => {\n    console.log(\n      {\n        success: processLogger.success,\n        failedClear: processLogger.failedClear,\n        failedSet: processLogger.failedSet,\n      },\n      `\\nDONE. ${processLogger.success.length} successful. ${processLogger.failedClear.length} failed to clear sessions. ${processLogger.failedSet.length} failed to set must_reconfirm.`\n    )\n  },\n}\n\nfunction _validateUserIdList(userIds) {\n  if (!Array.isArray(userIds)) throw new Error('users is not an array')\n\n  userIds.forEach(userId => {\n    if (!ObjectId.isValid(userId)) throw new Error('user ID not valid')\n  })\n}\n\nasync function _handleUser(userId) {\n  try {\n    await UserUpdater.promises.updateUser(userId, {\n      $set: { must_reconfirm: true },\n    })\n  } catch (error) {\n    console.log(`Failed to set must_reconfirm ${userId}`, error)\n    processLogger.failedSet.push(userId)\n    return\n  }\n\n  try {\n    await UserAuditLogHandler.promises.addEntry(\n      userId,\n      'must-reset-password-set',","sourceCodeStart":12,"sourceCodeEnd":48,"githubUrl":"https://github.com/overleaf/overleaf/blob/28ad3b03b71cb4311decdcb55c36b33ec10d72db/services/web/scripts/clear_sessions_set_must_reconfirm.mjs#L12-L48","documentation":"_validateUserIdList in clear_sessions_set_must_reconfirm.mjs iterates a list of user IDs and throws 'user ID not valid' for the first entry that is not a syntactically valid MongoDB ObjectId (per ObjectId.isValid). The script requires every line of the input file to be a 24-character hex string so it can pass real IDs to UserUpdater. It is an input-validation guard, not a database lookup: a well-formed-but-unknown ID would pass this check and fail later in _handleUser.","triggerScenarios":"Running `node clear_sessions_set_must_reconfirm.mjs users.txt` where the file contains a line that is not a valid ObjectId: an email instead of an ID, a truncated ID, whitespace-only or blank lines that survive trimming, or IDs copied with extra characters/quotes.","commonSituations":"Exporting user lists from logs or CSVs where a header row ('user_id') or non-user rows get mixed in; hand-edited ID files; older exports using a different ID format; forgetting the file is newline-separated ObjectIds.","solutions":["Open the users file and fix or remove the line that is not a 24-char hex ObjectId string (the error stops at the first bad ID).","Validate the file before running: grep -nEv '^[0-9a-fA-F]{24}$' users.txt to list bad lines.","Filter in code: users.map(s=>s.trim()).filter(s=>ObjectId.isValid(s)) before calling the script's helpers.","If IDs come from an upstream query, re-export using the correct projection (e.g. _id) so raw ObjectIds are written."],"exampleFix":"// before (users.txt)\nuser_id\n65d1f1e0c9e77d001a2b3c4\n// after (users.txt)\n65d1f1e0c9e77d001a2b3c4","handlingStrategy":"validation","validationCode":"import { ObjectId } from 'mongodb'\nconst ids = fs.readFileSync(file, 'utf8').trim().split('\\n').map(s => s.trim()).filter(Boolean)\nconst bad = ids.filter(id => !ObjectId.isValid(id))\nif (bad.length) throw new Error(`invalid ObjectIds at lines: ${bad.join(', ')}`)","typeGuard":"const isValidObjectId = (v) => typeof v === 'string' && /^[0-9a-fA-F]{24}$/.test(v)","tryCatchPattern":"try {\n  await script.run(userIds)\n} catch (err) {\n  if (err.message === 'user ID not valid') {\n    console.error('Bad ID in input file; sanitize with ObjectId.isValid filter')\n  } else throw err\n}","preventionTips":["Pre-sanitize input files with grep -nEv '^[0-9a-fA-F]{24}$' to find bad lines","Strip blank lines and whitespace before validating","Never mix emails and ObjectIds in one ID list","Validate the whole list, not just the first element, before invoking the script"],"tags":["input-validation","mongodb","objectid","cli-script"],"backgroundTag":"invalid-objectid","analyzedSha":"28ad3b03b71cb4311decdcb55c36b33ec10d72db","analyzedAt":"2026-09-03T02:10:22.807Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T07:17:11.731Z"}