sanity-io / sanity

Sanity Studio – Rapidly configure content workspaces powered by structured content
https://www.sanity.io
MIT License
5.08k stars 417 forks source link

Desk tool crash: editOpsOf does not expect a draft id #6704

Closed pacocoursey closed 2 days ago

pacocoursey commented 2 months ago

Describe the bug

The desk tool crashes when opening a draft document.

Error: editOpsOf does not expect a draft id.
    at getIdPairFromPublished (http://localhost:3333/node_modules/.sanity/vite/deps/chunk-SZUASH76.js?v=5cad09ac:109455:11)
    at Object.editState (http://localhost:3333/node_modules/.sanity/vite/deps/chunk-SZUASH76.js?v=5cad09ac:109517:31)
    at http://localhost:3333/node_modules/.sanity/vite/deps/chunk-SZUASH76.js?v=5cad09ac:133233:31
    at getValue (http://localhost:3333/node_modules/.sanity/vite/deps/chunk-SZUASH76.js?v=5cad09ac:36907:40)
    at http://localhost:3333/node_modules/.sanity/vite/deps/chunk-SZUASH76.js?v=5cad09ac:36957:12
    at mountMemo (http://localhost:3333/node_modules/.sanity/vite/deps/chunk-FIY3V743.js?v=5cad09ac:17409:27)
    at Object.useMemo (http://localhost:3333/node_modules/.sanity/vite/deps/chunk-FIY3V743.js?v=5cad09ac:17733:24)
    at useMemo (http://localhost:3333/node_modules/.sanity/vite/deps/chunk-LD72NT7V.js?v=5cad09ac:1094:29)
    at useMemoObservable (http://localhost:3333/node_modules/.sanity/vite/deps/chunk-SZUASH76.js?v=5cad09ac:36956:51)
    at useEditState (http://localhost:3333/node_modules/.sanity/vite/deps/chunk-SZUASH76.js?v=5cad09ac:133222:10)

To Reproduce

This is the schema of the document that is crashing the desk tool:

export const partnerList = defineType({
  name: "partners.list",
  title: "Partners",
  type: "document",
  fields: [
    {
      name: "list",
      title: "List",
      description: "List of partners",
      type: "array",
      of: [{ type: "partners.partner" }],
    },
  ],
});

Expected behavior

The desk tool should not crash.

Screenshots

iRVdtB2N@2x

Which versions of Sanity are you using?

@sanity/cli (global)        3.42.1 (up to date)
@sanity/cli                 3.42.1 (up to date)
@sanity/code-input           4.1.4 (up to date)
@sanity/preview-url-secret  1.6.13 (up to date)
@sanity/ui                  2.1.10 (up to date)
@sanity/vision              3.42.1 (up to date)
sanity                      3.42.1 (up to date)

What operating system are you using?

macOS 14.4.1

Which versions of Node.js / npm are you running?

pnpm 9.1.1 node 20.11.1

Additional context

N/A

bjoerge commented 2 months ago

Hi @pacocoursey – sorry you're running into this.

I'm not able to reproduce this, unfortunately. Any chance you could provide more details about the steps you took to get this error? Or provide a minimal and runnable repro project?

bjoerge commented 2 months ago

Closing due to inactivity

skyatlinear commented 1 month ago

@bjoerge Sky here. This activity is happening for me and paco reached out on my behalf. I'm uploading how I got to the page here.

https://github.com/sanity-io/sanity/assets/130077812/33786788-3f83-4b42-b582-d314ee24dd49

bjoerge commented 1 month ago

@skyatlinear do you happen to have any customizations in this studio? For example, any custom document actions?

skyatlinear commented 1 month ago

I just edited something and didn't see anything similar, but I'm not confident that's the best way to check. Is there a better way to confirm?

juice49 commented 1 month ago

Hi @skyatlinear. Customisations would be made in your Studio configuration file, which is usually named sanity.config.ts. It'd be best to check by looking in there. Do you have access to your Studio project's source code?

pacocoursey commented 1 week ago

Hey, sorry for the delay here.

We use a custom deskStructure.ts to organize the sidebar in places where we use singleton documents (i.e. only one of these document types should exist at once). In this case, we customize the link to our partners list using this logic:

async function findSingletonDocument(type) {
  const id = await client.fetch(`*[_type == "${type}"][0]._id`);
  return S.document().documentId(id).schemaType(type);
}

...
S.listItem()
  .title("Partners")
  .child(
    S.list()
      .title("Partners Documents")
      .items([
        S.listItem()
          .title("Partners Index")
          .child(async () => {
            return await findSingletonDocument("partners.page");
          }),
        S.divider(),
        S.listItem()
          .title("Partners List")
          .child(async () => {
            return await findSingletonDocument("partners.list");
          }),
      ])
  )
...

This leads to a studio URL like /structure/partners;partnersList (I guess the titles are slugified to generate that?) which then crashes the studio.

If we use a direct URL to the document like /structure/partners.list;e535e3e1-7b30-492c-8c9e-f0fc83e03234 then the studio does not crash.

runeb commented 2 days ago

Thanks for getting back to us with code, @pacocoursey

I feel confident that what is happening here is that your query finds a draft document, and the id passed to S.document().documentId(id).schemaType(type); contains the drafts. prefix. Sorry you are affected by this! We should handle this more gracefully behind the scenes.

This change should fix it

async function findSingletonDocument(type) {
  const id = await client.fetch(`*[_type == "${type}"][0]._id`);
  const cleanId = id.startsWith('drafts.') ? id.slice(7) : id; // Remove 'drafts.' prefix if present
  return ;
}

Usually singleton documents utilize manually chosen ids since there should only exist one document per type. You can then pick a nice readable one and use it like this:

S.listItem()
  .title("Partners")
  .child(
    S.list()
      .title("Partners Documents")
      .items([
        S.listItem()
          .title("Partners Index")
          .child(
            S.document().documentId('partners-page').schemaType('partners.page')
          ),
        S.divider(),
        S.listItem()
          .title("Partners List")
          .child(
            S.document().documentId('partners-list').schemaType('partners.list')
          ),
      ])
  )

Then you also don't need to make a query here which should speed up your Structure Tool.

The first time you navigate to these documents they won't exist, so you could use something like the sanity documents create cli command to easily bootstrap it if you have existing content you want to get it started with.

runeb commented 2 days ago

Should be solved with the above tips!

pacocoursey commented 1 day ago

That works, thanks!