Document service update() deep-populates the entry lookup, then only uses its id

Open Beginner friendly
#28,445 2 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 2 days

@hood is already working on this.

Since Nov 4, 2026.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
75/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
node.js, typescript

Research direction

Start in packages/core/core/src/services/document-service/repository.ts and trace how entryToUpdate is used after the lookup. Confirm those consumers only need its id, then check the Content Manager save path that passes buildDeepPopulate(uid). Done when the lookup selects only the id and a save no longer runs the full populate twice.

Written by the indexing model from the issue text.

Description

issue: bug severity: low source: core:core status: pending reproduction version: 5
Node Version

22.20.0

Package Manager

yarn

Package Manager Version

4.12.0

Strapi Version

5.61.0 (develop @ 958568e4ba)

Operating System

MacOS

Database

Other

Javascript or Typescript

Typescript

Bug Description

documents(uid).update() looks up the entry to update with the caller's fields and populate, then only reads its id.

In packages/core/core/src/services/document-service/repository.ts:

const query = transformParamsToQuery(uid, pickSelectionParams(restParams || {}));
const entryToUpdate = await strapi.db.query(uid).findOne({ ...query, where: { …, documentId } });

Every consumer of entryToUpdate (entries.update, the entity validator, components.updateComponents / deleteOldComponents) only reads entryToUpdate.id. The populate is applied again to the updated entry by db.update.

The Content Manager passes buildDeepPopulate(uid) (deep populate of every component, dynamic zone, media and relation count) on save, so each save runs one full deep read whose result is thrown away. On component or dynamic zone heavy types, that is dozens of queries per save.

Steps to Reproduce
  1. Create a content type with components and a dynamic zone
  2. Enable query debug logging (DEBUG=knex:query)
  3. Save an entry in the Content Manager
  4. See the full populate run twice: once for the lookup, once for the returned entry
Expected Behavior

The lookup selects only the id.

Additional information

Database agnostic: the cost is in application code.

Confirmation Checklist
Dominant language
TypeScript
Stars
73.5k
Forks
10k
Avg merge
3d 11h
Merged PRs (30d)
276

Getting set up

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.

More from strapi/strapi

All issues in strapi/strapi

Similar issues

More TypeScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.