Structure Builder singleton causing "List items with same ID found" error

10 replies
Last updated: Nov 29, 2025
v3
— Errors trying to implement a singleton.I'm following this:
https://www.sanity.io/docs/set-up-structure-builder-to-override-the-default-list-view and have this as my
sanity.config.ts

import {defineConfig} from 'sanity'
import {deskTool} from 'sanity/desk'
import {StructureBuilder} from 'sanity/desk'

const myStructure = (S: StructureBuilder) =>
  S.list()
    .title('Base')
    .items([
      S.listItem()
        .title('Site Settings')
        .child(S.document().schemaType('siteSettings').documentId('siteSettings')),
      ...S.documentTypeListItems(),
    ])

const mySchemaTypes = [
  {
    name: 'siteSettings',
    title: 'Site Settings',
    type: 'document',
    fields: [
      {
        name: 'title',
        title: 'Site Title',
        type: 'string',
      },
      {
        name: 'description',
        title: 'Site Description',
        type: 'text',
      },
    ],
  },
  {
    name: 'posts',
    type: 'document',
    title: 'Posts',
    fields: [
      {name: 'title', type: 'string', title: 'Title'},
      {name: 'slug', type: 'slug', title: 'Slug'},
      {name: 'content', type: 'array', title: 'Content', of: [{type: 'block'}]},
    ],
  },
]

export default defineConfig({
  name: 'default',
  title: 'sanity-11ty',

  projectId: import.meta.env.SANITY_STUDIO_PROJECT_ID,
  dataset: import.meta.env.SANITY_STUDIO_DATASET,

  plugins: [
    deskTool({
      structure: myStructure,
    }),
  ],

  schema: {
    types: mySchemaTypes,
  },
})
But get an error:
List items with same ID found (siteSettings)
What am I doing wrong?
AI Update

The error "List items with same ID found (siteSettings)" is happening because ...S.documentTypeListItems() is also creating a list item for your siteSettings document type, which conflicts with the custom singleton list item you created above it.

The solution is to filter out the singleton document type from the automatically generated list items. Here's your corrected config:

import {defineConfig} from 'sanity'
import {deskTool} from 'sanity/desk'
import {StructureBuilder} from 'sanity/desk'

const myStructure = (S: StructureBuilder) =>
  S.list()
    .title('Base')
    .items([
      // Your custom singleton
      S.listItem()
        .title('Site Settings')
        .child(S.document().schemaType('siteSettings').documentId('siteSettings')),
      // Filter out siteSettings from the auto-generated list
      ...S.documentTypeListItems().filter(
        (listItem) => listItem.getId() !== 'siteSettings'
      ),
    ])

// rest of your config...

The key change is adding .filter((listItem) => listItem.getId() !== 'siteSettings') to exclude the siteSettings document type from the automatically generated list items.

Additional recommendations for a proper singleton:

To fully implement a singleton document, you should also:

  1. Filter templates to prevent creating multiple instances via the "New document" menu:
export default defineConfig({
  // ... other config
  schema: {
    types: mySchemaTypes,
    templates: (templates) =>
      templates.filter(({ schemaType }) => schemaType !== 'siteSettings'),
  },
})
  1. Filter document actions to remove "duplicate" and "delete" actions:
export default defineConfig({
  // ... other config
  document: {
    actions: (input, context) =>
      context.schemaType === 'siteSettings'
        ? input.filter(({ action }) => action === 'publish')
        : input,
  },
})

You can find more details in the singleton document guide. Alternatively, consider using the singleton-tools plugin which handles all this configuration automatically.

Show original thread
10 replies

Sanity – Build the way you think, not the way your CMS thinks

Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.

Was this answer helpful?