Copy/paste of objects in array fields does not work with anonymous objects
Describe the bug
Copying and pasting array items (introduced in Sanity v3.54.0 in pull request #7292) requires the objects to have a name. If not provided, the error "Value of type "object" is not allowed in this array field" appears on the screen.
To Reproduce
This is an example of a simple schema that has an "Accordion" field. This is an array with anonymous objects.
import {defineType, defineField, defineArrayMember} from 'sanity'
export const page = defineType({
type: 'document',
name: 'page',
fields: [
defineField({
type: 'string',
name: 'title',
}),
defineField({
type: 'slug',
name: 'slug',
options: {
source: 'title',
maxLength: 96,
},
}),
defineField({
type: 'array',
name: 'accordion',
title: 'Accordion',
of: [
defineArrayMember({
type: 'object',
fields: [
defineField({
type: 'string',
name: 'title',
}),
defineField({
type: 'text',
name: 'content',
}),
],
}),
],
}),
],
})
To replicate the issue, try to open this in the Sanity studio, create a page with an accordion array item, and lastly try to copy/paste the row.
Expected behavior
Because naming your objects in array fields isn't mandatory (if you don't have multiple objects available in the same array field), I would expect copy/pasting anonymous objects in array fields to work.
Screenshots
This is the error message I get when trying to copy and paste an accordion item:
Which versions of Sanity are you using?
@sanity/eslint-config-studio 4.0.0 (up to date)
@sanity/vision 3.60.0 (up to date)
sanity 3.60.0 (up to date)
Hello everyone! We have an internal ticket for this and will update things accordingly - indeed anonymous objects will cause issues with copy&paste. As a workaround, you can add name attributes to your inline objects. Don't forget to also change existing array items
Hello.
Still have the same issue even with Copy field & Paste field. Any updates or fixes?
We've also encountered this issue. Update would be appreciated!
➕
Hello everyone! The fix is adding a name attribute to your inline objects as detailed here
This will only apply to new data, and you will need to add the missing name to your existing data using a Content Migration script.
You can find the anonymous objects in an array by looking for any items, that have no _type set (see screenshot). While usually the _type attributes cannot be changed via migration scripts, this does not apply for anonymous inline objects, so you will be able to run a simple migration script to resolve the issue
example
import { at, defineMigration, setIfMissing } from 'sanity/migrate'
export default defineMigration({
title: 'Add missing name attributes to anonymous objects',
documentTypes: ['testDocument'],
migrate: {
document(doc, context) {
// REPLACE THIS WITH YOUR SCHEMA STRUCTURE
const copyPasteArray = doc.copyPasteArray as {
title: string
_key: string
_type?: string
}[]
if (
doc.copyPasteArray &&
copyPasteArray.some((item) => item._type === undefined)
) {
return copyPasteArray
.filter((item) => item._type === undefined)
.map((item) => {
return at(
['copyPasteArray', { _key: item._key }, '_type'],
setIfMissing('namedObject'),
)
})
}
},
},
})
⚠️ ⚠️ ⚠️
DO NOT try to write one migration script for all anonymous objects to make sure you don't cause issues in other places and test them well. ALWAYS create a backup before running the script in dryMode and read the content migration script docs well
result
Initial data
resulting data after migration
Hello. Any updates? We have a lot of nested objects, arrays, so this functionality is critical for us and can not be fixed using the mentioned methods
Is there any update on the progress? If the name is required, it would be nice with an error from TS. This bug often gets noticed after editors hav added data.