{"record":{"id":"ab28cf67fefe1a2c","repo":"mastra-ai/mastra","slug":"dataset-item-external-id-invalid-ab28cf","errorCode":"DATASET_ITEM_EXTERNAL_ID_INVALID","errorMessage":"error.message (DATASET_ITEM_EXTERNAL_ID_INVALID, cause: field externalId)","messagePattern":"error\\.message \\(DATASET_ITEM_EXTERNAL_ID_INVALID, cause: field externalId\\)","errorType":"error_code","errorClass":"HTTPException","httpStatus":400,"severity":"error","filePath":"packages/server/src/server/handlers/datasets.ts","lineNumber":1229,"sourceCode":"        items: items.map(item => ({ ...item, externalId: item.externalId ?? undefined })),\n      });\n      return { items: addedItems, count: addedItems.length };\n    } catch (error) {\n      if (isSchemaValidationError(error)) {\n        throw new HTTPException(400, {\n          message: error.message,\n          cause: { field: error.field, errors: error.errors },\n        });\n      }\n      if (error instanceof MastraError) {\n        if (error.id === 'DATASET_ITEM_IDENTITY_CONFLICT') {\n          throw new HTTPException(409, {\n            message: error.message,\n            cause: { conflicts: 'conflicts' in error ? error.conflicts : [] },\n          });\n        }\n        if (error.id === 'DATASET_ITEM_EXTERNAL_ID_INVALID') {\n          throw new HTTPException(400, { message: error.message, cause: { field: 'externalId' } });\n        }\n        throw new HTTPException(getHttpStatusForMastraError(error.id) as StatusCode, { message: error.message });\n      }\n      return handleError(error, 'Error batch inserting items');\n    }\n  },\n});\n\nexport const BATCH_DELETE_ITEMS_ROUTE = createRoute({\n  method: 'DELETE',\n  path: '/datasets/:datasetId/items/batch',\n  responseType: 'json',\n  pathParamSchema: datasetIdPathParams,\n  bodySchema: batchDeleteItemsBodySchema,\n  responseSchema: batchDeleteItemsResponseSchema,\n  summary: 'Batch delete items from dataset',\n  description: 'Deletes multiple items from the dataset in a single operation (single version entry)',\n  tags: ['Datasets'],","sourceCodeStart":1211,"sourceCodeEnd":1247,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/server/src/server/handlers/datasets.ts#L1211-L1247","documentation":"When an item's externalId fails validation (wrong type, empty, or otherwise invalid per DATASET_ITEM_EXTERNAL_ID_INVALID), the handler maps the MastraError to HTTP 400 with cause: { field: 'externalId' }, pointing the caller at the offending field.","triggerScenarios":"POST /datasets/:datasetId/items/batch with an item whose externalId is not a valid string (e.g. a number, null leaked explicitly, empty string, or an object) — note the handler normalizes undefined to undefined, but explicit nulls/other types can trip storage validation.","commonSituations":"Passing numeric IDs from an external system without String() conversion; sending null instead of omitting the field; copying items between datasets where externalId types differ; form data coercing values incorrectly.","solutions":["Coerce externalId to a non-empty string (or omit it entirely) for every item in the batch.","Normalize null to undefined before sending: externalId: item.externalId ?? undefined.","Validate each item's externalId client-side before the request.","Check upstream data sources for numeric or whitespace-only IDs and trim/cast them."],"exampleFix":"// before\nitems: [{ externalId: 12345, input }]\n// after\nitems: [{ externalId: String(12345), input }]","handlingStrategy":"validation","validationCode":"function isValidExternalId(v: unknown): boolean {\n  return v === undefined || (typeof v === 'string' && v.trim().length > 0);\n}\nitems.forEach(i => {\n  if (!isValidExternalId(i.externalId)) throw new Error(`Invalid externalId: ${JSON.stringify(i.externalId)}`);\n  if (i.externalId === null) delete i.externalId; // send undefined, not null\n});","typeGuard":"function hasValidExternalId(item: { externalId?: unknown }): item is { externalId?: string } {\n  return item.externalId === undefined ||\n    (typeof item.externalId === 'string' && item.externalId.trim().length > 0);\n}","tryCatchPattern":"try {\n  return await batchInsertItems(datasetId, items);\n} catch (err) {\n  if (err.status === 400 && err.body?.cause?.field === 'externalId') {\n    console.error('externalId rejected; coercing and retrying once');\n    const fixed = items.map(i => ({ ...i, externalId: i.externalId == null ? undefined : String(i.externalId) }));\n    return batchInsertItems(datasetId, fixed);\n  }\n  throw err;\n}","preventionTips":["Coerce numeric external IDs with String() at the boundary with external systems.","Omit externalId entirely instead of sending null when absent.","Add a shared normalize step for batch payloads (trim, stringify, drop empties).","Type externalId as string | undefined (not string | null | number) in client code."],"tags":["http-400","validation","external-id","datasets","batch-insert"],"backgroundTag":"invalid-field-value","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}