{"record":{"id":"fc14d8970b591f47","repo":"yikart/AiToEarn","slug":"responsecode-validationfailed","errorCode":"ResponseCode.ValidationFailed","errorMessage":"ValidationFailed","messagePattern":"ValidationFailed","errorType":"error_code","errorClass":"AppException","httpStatus":null,"severity":"error","filePath":"project/aitoearn-backend/libs/common/src/pipes/parse-object-id.pipe.ts","lineNumber":12,"sourceCode":"import { Injectable, PipeTransform } from '@nestjs/common'\nimport { isValidObjectId } from 'mongoose'\nimport { ResponseCode } from '../enums'\nimport { AppException } from '../exceptions'\n\n@Injectable()\nexport class ParseObjectIdPipe implements PipeTransform<string | undefined> {\n  transform(value: string | undefined): string | undefined {\n    if (value === undefined || value === null)\n      return value\n    if (!isValidObjectId(value)) {\n      throw new AppException(ResponseCode.ValidationFailed)\n    }\n    return value\n  }\n}\n","sourceCodeStart":1,"sourceCodeEnd":17,"githubUrl":"https://github.com/yikart/AiToEarn/blob/d3aa8bea5b146a8675607cf0144d891aad3e9683/project/aitoearn-backend/libs/common/src/pipes/parse-object-id.pipe.ts#L1-L17","documentation":"ValidationFailed is thrown by ParseObjectIdPipe when a supplied string route/query parameter is defined but not a valid MongoDB ObjectId (24-char hex). Nest pipes run before the handler, so the request is rejected early with the standard ValidationFailed response code.","triggerScenarios":"Passing a non-ObjectId string (numeric DB id, UUID, short code, empty-string after trimming) to a param decorated with @Param('id', ParseObjectIdPipe).","commonSituations":"Frontend switched from numeric IDs to ObjectIds (or vice versa) after a storage migration; IDs truncated in URLs; client stores IDs as JSON and loses formatting; testing with hardcoded placeholder IDs like '1' or 'test'.","solutions":["Ensure the client sends the actual 24-hex-char MongoDB _id","Validate the ID format client-side (/^[0-9a-fA-F]{24}$/) before calling","Check for truncation/sanitization in routing or query-string handling","If legacy numeric IDs must be supported, remove the pipe or add a custom union pipe"],"exampleFix":"// before\napi.get(`/users/${numericId}`) // numericId = 42\n// after\nif (!/^[0-9a-f]{24}$/.test(id)) throw new Error('invalid id')\napi.get(`/users/${id}`)","handlingStrategy":"validation","validationCode":"const OBJECT_ID_RE = /^[0-9a-fA-F]{24}$/\nif (!OBJECT_ID_RE.test(id)) throw new Error(`invalid ObjectId: ${id}`)","typeGuard":"function isObjectId(v: unknown): v is string {\n  return typeof v === 'string' && /^[0-9a-fA-F]{24}$/.test(v)\n}","tryCatchPattern":"try {\n  await api.get(`/items/${id}`)\n} catch (e) {\n  if (e.response?.data?.code === 'ValidationFailed') {\n    // surface 'invalid id' to user instead of generic failure\n  } else throw e\n}","preventionTips":["Always use the raw MongoDB _id string from the API response","Validate 24-hex-char format client-side before requests","Watch for ID truncation in URL builders/templating","Migrate clients fully when switching ID schemes"],"tags":["validation","mongodb","objectid","pipe"],"backgroundTag":"invalid-object-id","analyzedSha":"d3aa8bea5b146a8675607cf0144d891aad3e9683","analyzedAt":"2026-08-31T14:19:24.185Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}