{"record":{"id":"4c2d4bdbab0a45fd","repo":"nocobase/nocobase","slug":"illegal-percentage-format","errorCode":null,"errorMessage":"Illegal percentage format","messagePattern":"Illegal percentage format","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/plugins/@nocobase/plugin-action-import/src/server/utils/transform.ts","lineNumber":128,"sourceCode":"  }\n  return m.toDate();\n}\nexport async function time({ value, field, ctx }) {\n  const { format } = field.options?.uiSchema?.['x-component-props'] ?? {};\n  if (format) {\n    const m = dayjs(value, format);\n    if (!m.isValid()) {\n      throw new Error(ctx.t('Incorrect time format', { ns: namespace }));\n    }\n    return m.format(format);\n  }\n  return value;\n}\nexport async function percent({ value, field, ctx }) {\n  if (value) {\n    const numberValue = Number(value?.split('%')?.[0] ?? value);\n    if (isNaN(numberValue)) {\n      throw new Error(ctx.t('Illegal percentage format', { ns: namespace }));\n    }\n    return math.round(numberValue / 100, 9);\n  }\n  return 0;\n}\nexport async function checkbox({ value, column, field, ctx }) {\n  return value === ctx.t('Yes', { ns: namespace }) ? 1 : 0;\n}\n\nexport const boolean = checkbox;\n\nexport async function select({ value, column, field, ctx }) {\n  const { enum: enumData } = column;\n  const item = enumData.find((item) => item.label === value);\n  return item?.value;\n}\nexport const radio = select;\n","sourceCodeStart":110,"sourceCodeEnd":146,"githubUrl":"https://github.com/nocobase/nocobase/blob/fa42722fefe44265490dff2c27d79e2882bce4fa/packages/plugins/@nocobase/plugin-action-import/src/server/utils/transform.ts#L110-L146","documentation":"The percent transform strips a trailing '%' via split('%')[0], coerces the result with Number(), and throws 'Illegal percentage format' when the numeric coercion yields NaN. Valid values are divided by 100 and rounded to 9 decimals; an empty/falsy value returns 0 instead of throwing.","triggerScenarios":"Cells containing text like 'twelve percent', '12 %x', currency symbols ('$12%'), thousands separators in locales where Number() rejects them ('12,5%'), or whitespace/space-embedded values that fail Number parsing.","commonSituations":"Regional decimal commas ('12,5%') which JavaScript Number cannot parse; percent columns formatted as text with stray characters; copy-paste from documents bringing non-numeric glyphs.","solutions":["Enter the value as a plain number, with or without a trailing % (e.g. '12%' or '12'), using a dot as decimal separator","Replace decimal commas with dots in the spreadsheet (or set the sheet's locale/format to US)","Remove currency symbols, spaces inside the number, and other non-numeric characters","Verify the column is numeric-formatted, not text, before exporting/importing"],"exampleFix":"// before\npercent: \"12,5%\"\n// after\npercent: \"12.5%\"","handlingStrategy":"validation","validationCode":"// pre-validate percent strings parse to numbers\nfunction parsePercent(value: string): number {\n  const n = Number(value.split('%')[0] ?? value);\n  if (Number.isNaN(n)) throw new Error(`Illegal percent: ${value}`);\n  return n / 100;\n}","typeGuard":"function isValidPercent(value: unknown): value is string | number {\n  if (typeof value === 'number') return !Number.isNaN(value);\n  return typeof value === 'string' && !Number.isNaN(Number(value.replace(/%$/, '').trim()));\n}","tryCatchPattern":"try {\n  await importer.import(file);\n} catch (err) {\n  if (String(err.message).includes('Illegal percentage format')) {\n    // find non-numeric percent cells and clean them\n  }\n  throw err;\n}","preventionTips":["Use dot decimals, not commas, in percent cells","Format the column as numeric in the spreadsheet","Strip currency symbols and stray spaces before import","Remember: empty cells import as 0 — decide if that's acceptable"],"tags":["validation","percent","import"],"backgroundTag":"invalid-number-format","analyzedSha":"fa42722fefe44265490dff2c27d79e2882bce4fa","analyzedAt":"2026-09-01T00:54:31.202Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}