payloadcms / payloadcms/payload

fix(plugin-import-export): the import with CSV file doesn't populate fields correctly

Open
#17,118 1 comment 0 reactions 1 assignee View on GitHub

@nathanlentz is already working on this.

Since Jul 24, 2026.

invalid-reproduction plugin: import-export v3
Dominant language
TypeScript
Stars
44.8k
Forks
4.2k
Avg merge
2d 21h
Merged PRs (30d)
53

Description

Describe the Bug

When fields are formatted in snake_case, they are not imported correctly. This issue occurs because the import/export plugin relies on the underscore character (_) within CSV files to identify the nesting of field groups. Consequently, it misinterprets the snake_case field names as nested groups rather than flat fields.

The plugin should be able to distinguish between standard snake_case field names and the underscores used for group nesting, allowing snake_case fields to be imported and exported correctly without data loss or mapping errors.

Here is where is the function that doesn't manage this particular case:

packages/plugin-import-export/src/utilities/unflattenObject.ts

This is test file that doesn't manage this case:

packages/plugin-import-export/src/utilities/unflattenObject.spec.ts

This is the test that should pass:

describe('fields with any permitted name types', () => {
const fields: FlattenedField[] = [
{
name: 'simple',
type: 'text',
} as FlattenedField,
{
name: 'camelCase',
type: 'text',
} as FlattenedField,
{
name: 'PascalCase',
type: 'text',
} as FlattenedField,
{
name: 'with_underscores',
type: 'text',
} as FlattenedField,
{
name: '_start_with_underscore',
type: 'text',
} as FlattenedField,
{
name: 'with_numbers_1',
type: 'text',
} as FlattenedField,
{
name: 'localized_with_underscores_with_numbers_1',
type: 'text',
localized: true,
} as FlattenedField,
]

it('should handle documented fields names', () => {
const data = {
simple: 'simple',
camelCase: 'camelCase',
PascalCase: 'PascalCase',
with_underscores: 'with_underscores',
_start_with_underscore: '_start_with_underscore',
with_numbers_1: 'with_numbers_1',
localized_with_underscores_with_numbers_1_en: 'localized_with_underscores_with_numbers_1_en',
localized_with_underscores_with_numbers_1_es: 'localized_with_underscores_with_numbers_1_es',
}

const result = unflattenObject({ data, fields, req: mockReq })

expect(result).toEqual({
simple: 'simple',
camelCase: 'camelCase',
PascalCase: 'PascalCase',
with_underscores: 'with_underscores',
_start_with_underscore: '_start_with_underscore',
with_numbers_1: 'with_numbers_1',
localized_with_underscores_with_numbers_1: {
en: 'localized_with_underscores_with_numbers_1_en',
es: 'localized_with_underscores_with_numbers_1_es',
},
})
})

const groupFields: FlattenedField[] = [
{
name: 'group',
type: 'group',
flattenedFields: [
...fields,
],
} as FlattenedField,
]

it('should handle documented fields names nested', () => {
const data = {
group_simple: 'simple',
group_camelCase: 'camelCase',
group_PascalCase: 'PascalCase',
group_with_underscores: 'with_underscores',
group__start_with_underscore: '_start_with_underscore',
group_with_numbers_1: 'with_numbers_1',
group_localized_with_underscores_with_numbers_1_en: 'localized_with_underscores_with_numbers_1_en',
group_localized_with_underscores_with_numbers_1_es: 'localized_with_underscores_with_numbers_1_es',
}

const result = unflattenObject({ data, fields: groupFields, req: mockReq })

expect(result).toEqual({
group: {
simple: 'simple',
camelCase: 'camelCase',
PascalCase: 'PascalCase',
with_underscores: 'with_underscores',
_start_with_underscore: '_start_with_underscore',
with_numbers_1: 'with_numbers_1',
localized_with_underscores_with_numbers_1: {
en: 'localized_with_underscores_with_numbers_1_en',
es: 'localized_with_underscores_with_numbers_1_es',
},
},
})
})
})
Link to the code that reproduces this issue

https://github.com/TommasoCappelletti/payload-issue-plugin-import-export.git

Reproduction Steps
  • Export the data to a CSV (select the vat_number field);
  • Modify the CSV (the vat_number field);
  • Attempt to import the CSV;
  • See that the vat_number field has not been updated.
Which area(s) are affected?

plugin: import-export

Environment Info
Binaries:
  Node: 22.22.0
  npm: 10.9.4
  Yarn: 3.8.6
  pnpm: N/A
Relevant Packages:
  payload: 3.85.0
Operating System:
  Platform: linux
  Arch: x64
  Version: #35~24.04.1-Ubuntu SMP PREEMPT_DYNAMIC Tue May 26 19:30:42 UTC 2
  Available memory (MB): 63500
  Available CPU cores: 16

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.