nocobase/nocobase · error

Illegal percentage format

Error message

Illegal percentage format

What it means

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.

Source

Thrown at packages/plugins/@nocobase/plugin-action-import/src/server/utils/transform.ts:128

  }
  return m.toDate();
}
export async function time({ value, field, ctx }) {
  const { format } = field.options?.uiSchema?.['x-component-props'] ?? {};
  if (format) {
    const m = dayjs(value, format);
    if (!m.isValid()) {
      throw new Error(ctx.t('Incorrect time format', { ns: namespace }));
    }
    return m.format(format);
  }
  return value;
}
export async function percent({ value, field, ctx }) {
  if (value) {
    const numberValue = Number(value?.split('%')?.[0] ?? value);
    if (isNaN(numberValue)) {
      throw new Error(ctx.t('Illegal percentage format', { ns: namespace }));
    }
    return math.round(numberValue / 100, 9);
  }
  return 0;
}
export async function checkbox({ value, column, field, ctx }) {
  return value === ctx.t('Yes', { ns: namespace }) ? 1 : 0;
}

export const boolean = checkbox;

export async function select({ value, column, field, ctx }) {
  const { enum: enumData } = column;
  const item = enumData.find((item) => item.label === value);
  return item?.value;
}
export const radio = select;

View on GitHub (pinned to fa42722fef)

Solutions

  1. Enter the value as a plain number, with or without a trailing % (e.g. '12%' or '12'), using a dot as decimal separator
  2. Replace decimal commas with dots in the spreadsheet (or set the sheet's locale/format to US)
  3. Remove currency symbols, spaces inside the number, and other non-numeric characters
  4. Verify the column is numeric-formatted, not text, before exporting/importing

Example fix

// before
percent: "12,5%"
// after
percent: "12.5%"
Defensive patterns

Strategy: validation

Validate before calling

// pre-validate percent strings parse to numbers
function parsePercent(value: string): number {
  const n = Number(value.split('%')[0] ?? value);
  if (Number.isNaN(n)) throw new Error(`Illegal percent: ${value}`);
  return n / 100;
}

Type guard

function isValidPercent(value: unknown): value is string | number {
  if (typeof value === 'number') return !Number.isNaN(value);
  return typeof value === 'string' && !Number.isNaN(Number(value.replace(/%$/, '').trim()));
}

Try / catch

try {
  await importer.import(file);
} catch (err) {
  if (String(err.message).includes('Illegal percentage format')) {
    // find non-numeric percent cells and clean them
  }
  throw err;
}

Prevention

When it happens

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

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

Related errors


AI-assisted analysis of nocobase/nocobase@fa42722fef (2026-09-01). Data as JSON: /api/errors/4c2d4bdbab0a45fd. Report an issue: GitHub.