mastra-ai/mastra · error · HTTPException

DATASET_ITEM_EXTERNAL_ID_INVALID

DATASET_ITEM_EXTERNAL_ID_INVALID

Error message

error.message (DATASET_ITEM_EXTERNAL_ID_INVALID, cause: field externalId)

What it means

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.

Source

Thrown at packages/server/src/server/handlers/datasets.ts:1229

        items: items.map(item => ({ ...item, externalId: item.externalId ?? undefined })),
      });
      return { items: addedItems, count: addedItems.length };
    } catch (error) {
      if (isSchemaValidationError(error)) {
        throw new HTTPException(400, {
          message: error.message,
          cause: { field: error.field, errors: error.errors },
        });
      }
      if (error instanceof MastraError) {
        if (error.id === 'DATASET_ITEM_IDENTITY_CONFLICT') {
          throw new HTTPException(409, {
            message: error.message,
            cause: { conflicts: 'conflicts' in error ? error.conflicts : [] },
          });
        }
        if (error.id === 'DATASET_ITEM_EXTERNAL_ID_INVALID') {
          throw new HTTPException(400, { message: error.message, cause: { field: 'externalId' } });
        }
        throw new HTTPException(getHttpStatusForMastraError(error.id) as StatusCode, { message: error.message });
      }
      return handleError(error, 'Error batch inserting items');
    }
  },
});

export const BATCH_DELETE_ITEMS_ROUTE = createRoute({
  method: 'DELETE',
  path: '/datasets/:datasetId/items/batch',
  responseType: 'json',
  pathParamSchema: datasetIdPathParams,
  bodySchema: batchDeleteItemsBodySchema,
  responseSchema: batchDeleteItemsResponseSchema,
  summary: 'Batch delete items from dataset',
  description: 'Deletes multiple items from the dataset in a single operation (single version entry)',
  tags: ['Datasets'],

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Coerce externalId to a non-empty string (or omit it entirely) for every item in the batch.
  2. Normalize null to undefined before sending: externalId: item.externalId ?? undefined.
  3. Validate each item's externalId client-side before the request.
  4. Check upstream data sources for numeric or whitespace-only IDs and trim/cast them.

Example fix

// before
items: [{ externalId: 12345, input }]
// after
items: [{ externalId: String(12345), input }]
Defensive patterns

Strategy: validation

Validate before calling

function isValidExternalId(v: unknown): boolean {
  return v === undefined || (typeof v === 'string' && v.trim().length > 0);
}
items.forEach(i => {
  if (!isValidExternalId(i.externalId)) throw new Error(`Invalid externalId: ${JSON.stringify(i.externalId)}`);
  if (i.externalId === null) delete i.externalId; // send undefined, not null
});

Type guard

function hasValidExternalId(item: { externalId?: unknown }): item is { externalId?: string } {
  return item.externalId === undefined ||
    (typeof item.externalId === 'string' && item.externalId.trim().length > 0);
}

Try / catch

try {
  return await batchInsertItems(datasetId, items);
} catch (err) {
  if (err.status === 400 && err.body?.cause?.field === 'externalId') {
    console.error('externalId rejected; coercing and retrying once');
    const fixed = items.map(i => ({ ...i, externalId: i.externalId == null ? undefined : String(i.externalId) }));
    return batchInsertItems(datasetId, fixed);
  }
  throw err;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/ab28cf67fefe1a2c. Report an issue: GitHub.