{"record":{"id":"ca2b6d162fb08afb","repo":"nocobase/nocobase","slug":"incorrect-email-format","errorCode":null,"errorMessage":"Incorrect email format","messagePattern":"Incorrect email format","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/plugins/@nocobase/plugin-action-import/src/server/utils/transform.ts","lineNumber":24,"sourceCode":" * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.\n * For more information, please refer to: https://www.nocobase.com/agreement.\n */\n\nimport { dayjs, str2moment } from '@nocobase/utils';\nimport * as math from 'mathjs';\nimport { namespace } from '../../';\n\nexport async function _({ value, field }) {\n  return value;\n}\n\nexport async function email({ value, field, ctx }) {\n  if (!value?.trim()) {\n    return value;\n  }\n  const emailReg = /^([a-zA-Z0-9._-])+@([a-zA-Z0-9_-])+(\\.[a-zA-Z0-9_-])+/;\n  if (!emailReg.test(value)) {\n    throw new Error(ctx.t('Incorrect email format', { ns: namespace }));\n  }\n  return value;\n}\n\nexport async function password({ value, field, ctx }) {\n  if (value === undefined || value === null) {\n    throw new Error(ctx.t('password is empty', { ns: namespace }));\n  }\n  return `${value}`;\n}\n\nexport async function o2o({ value, column, field, ctx }) {\n  const { dataIndex, enum: enumData } = column;\n  const repository = ctx.db.getRepository(field.options.target);\n  let enumItem = null;\n  if (enumData?.length > 0) {\n    enumItem = enumData.find((e) => e.label === value);\n  }","sourceCodeStart":6,"sourceCodeEnd":42,"githubUrl":"https://github.com/nocobase/nocobase/blob/fa42722fefe44265490dff2c27d79e2882bce4fa/packages/plugins/@nocobase/plugin-action-import/src/server/utils/transform.ts#L6-L42","documentation":"The email transform validates each imported email value against a permissive regex before persisting it and throws when the value does not match. Empty/whitespace-only values are passed through untouched. This is thrown as a plain Error whose message is already translated via ctx.t, surfacing to the import UI as a row-level failure.","triggerScenarios":"An imported cell contains text like 'alice', 'a@', 'alice at x.com', or has stray characters/unicode the regex rejects, while being non-empty. The regex requires local-part@domain.tld with each dot-separated label non-empty.","commonSituations":"Copy-pasted contact lists with display names ('Alice <a@x.com>'), trailing punctuation ('a@x.com.'), concatenated columns, or placeholder values ('N/A') in the email column.","solutions":["Correct the offending cell to a plain valid email like user@example.com","Trim leading/trailing characters and remove display-name or bracket wrappers","Check for invisible characters (zero-width spaces, RTL marks) when the value looks valid; retype the value","If the source data is bulk-invalid, clean it in the spreadsheet with a validation formula before import"],"exampleFix":"// before\nemail: \"Alice <alice@example.com>\"\n// after\nemail: \"alice@example.com\"","handlingStrategy":"validation","validationCode":"const emailReg = /^([a-zA-Z0-9._-])+@([a-zA-Z0-9_-])+(\\.[a-zA-Z0-9_-])+/;\nif (value?.trim() && !emailReg.test(value)) {\n  throw new Error(`Invalid email in row: ${value}`);\n}","typeGuard":"function isValidEmail(value: unknown): value is string {\n  return typeof value === 'string' && /^([a-zA-Z0-9._-])+@([a-zA-Z0-9_-])+(\\.[a-zA-Z0-9_-])+/.test(value);\n}","tryCatchPattern":"try {\n  await importer.import(file);\n} catch (err) {\n  if (String(err.message).includes('Incorrect email format')) {\n    // surface row location to user and skip/fix the row\n  }\n  throw err;\n}","preventionTips":["Apply spreadsheet data-validation (email) on the column before distributing the template","Clean copy-pasted contact data of display names and brackets","Watch for invisible Unicode characters in look-valid emails","Trim and normalize the column with spreadsheet functions before import"],"tags":["validation","email","import"],"backgroundTag":"invalid-email-format","analyzedSha":"fa42722fefe44265490dff2c27d79e2882bce4fa","analyzedAt":"2026-09-01T00:54:31.202Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}