Skip to main content

Updating repeatable components with the Document Service API is not recommended

Page summary:

In Strapi 5, draft and published versions of a document use different numeric component ids. Reusing an id from a published response to update the draft usually fails. Prefer replacing the full component array (or editing against draft ids) until a durable component identity ships.

In Strapi 5, it's not recommended to update repeatable components by reusing component ids from published API responses, because of how Draft & Publish interacts with the Document Service API.

This page is part of the breaking changes database and provides information about the breaking change and additional instructions to migrate from Strapi v4 to Strapi 5.

 Is this breaking change affecting plugins?Yes
 Is this breaking change automatically handled by a codemod?No

Breaking change description

In Strapi v4

You could partially update a repeatable component by passing its numeric id.

In Strapi 5

Documents use a stable documentId, but nested components still use status-local numeric ids. Publishing creates new component rows, so the draft and published versions of the same block have different ids. You cannot treat a published component id like a document-level identifier.

Migration

This section regroups useful notes and procedures about the introduced breaking change.

Notes

With Draft & Publish enabled, a typical Content API flow looks like this:

// Request: Content API returns the published version by default
GET /api/articles

// Response (published)
{
data: {
documentId: '…',
components: [
{ id: 2, name: 'component-1' },
{ id: 4, name: 'component-2' },
],
},
}

Updating with those published ids writes the draft, which has different component row ids:

PUT /api/articles/{documentId}
{
data: {
components: [
{ id: 2, name: 'component-1-updated' }, // published id, usually wrong for draft
],
},
}

This often fails with an error such as Some of the provided components in components are not related to the entity, because id: 2 is not linked to the draft entry. This is related to the fact that components and dynamic zones do not return an id in REST API responses.

The Document Service defaults to the draft on read/update, so in-place updates by id can work there (and in the Content Manager) when you use draft component ids. The trap is mixing published ids with draft writes.

Until a durable nested identity is available, use one of the following.

1. Replace the full component array (preferred for Content API)

Omit component ids and send the complete desired list. Strapi recreates the components on the draft. This is the supported, non-fragile approach for REST/GraphQL clients that only see published data:

// Document Service
await strapi.documents('api::article.article').update({
documentId,
data: {
components: [
{ name: 'component-1-updated' },
{ name: 'component-2' },
],
},
});
// REST Content API
PUT /api/articles/{documentId}
{
"data": {
"components": [
{ "name": "component-1-updated" },
{ "name": "component-2" }
]
}
}
Tip

Include every component you want to keep. Entries omitted from the array are removed from the draft.

2. Edit against draft component ids (Document Service / admin-style)

If you control the backend (custom routes, scripts, Document Service), load the draft, then update using those ids:

const draft = await strapi.documents('api::article.article').findOne({
documentId,
status: 'draft',
populate: ['components'],
});

await strapi.documents('api::article.article').update({
documentId,
data: {
components: draft.components.map((component) =>
component.id === targetDraftId
? { id: component.id, name: 'component-1-updated' }
: { id: component.id, name: component.name }
),
},
});

Do not reuse ids from a default Content API GET (published) for this pattern.

3. Draft & Publish disabled

If Draft & Publish is disabled on the content-type, there is only one component row set, so id-based updates are less problematic. Prefer the full-array replace pattern anyway for simpler client code.

Was this page helpful?