Skip to content

[Bug] Completed Knowledge documents remain locked after disabling or re-enabling #44598

Open

Description

@laipz8200

Self Checks

  • I have read the Contributing Guide and Language Policy.
  • This is only for bug report, if you would like to ask a question, please head to Discussions.
  • I have searched for existing issues search for existing issues, including closed ones.
  • I confirm that I am using English to submit this report, otherwise it will be closed.
  • 【中文用户 & Non English User】请使用英语提交,否则会被关闭 :)
  • Please do not modify this template :) and fill in all the required fields.

Dify version

1.18.0 release candidate, commit 720d8489453cea51c26382e43f4b8ba7024a6dca, tested during #44546 release verification on 2026-10-23.

Cloud or Self Hosted

Self Hosted (Source). Production web build on macOS with Chromium; isolated local API/worker and Docker infrastructure.

Steps to reproduce

  1. Create a Classic Knowledge base using economical indexing.
  2. Upload a small plain-text file, such as qa-handbook.txt, and wait until indexing is complete and the document is Available/enabled.
  3. In the Documents list, disable the document.
  4. Wait for the removal worker to complete, then enable the document again.
  5. If the race occurs, retry or reload: the document remains disabled and re-enabling returns an indexing error. This is timing-dependent and is easiest to reproduce with a small document and a fast local worker.
  6. The equivalent stale lock after re-enabling also blocks chunk enable/disable operations.

No artificial network or worker delay was used for this recording.

Reproduction video — 14 seconds

bug-01-document-reenable-final.mp4

✔️ Expected Behavior

After the indexing worker finishes, the completed document can be enabled again and its chunks can be edited. The indexing lock should cover the actual background operation and be removed when that operation finishes.

❌ Actual Behavior

The UI shows Modified unsuccessfully. The enable request returns HTTP 400 even though the removal task has already completed:

{
  "code": "invalid_action",
  "message": "Document:qa-handbook.txt is being indexed, please try again later",
  "status": 400
}

Observed request/worker ordering (UTC):

04:44:48.663  document disable response: HTTP 200
04:44:48      Document removed from index; latency: 0.009748916840180755 s
04:44:48      remove_document_from_index_task succeeded in 0.010733916889876127 s
04:44:50.516  document enable response: HTTP 400, invalid_action
04:46:11.525  document_<document-id>_indexing = 1; TTL = 517 seconds

The Redis lock is written with a 600-second lifetime even though the worker completed in about 10 ms. Waiting for natural expiry allowed chunk disable/re-enable to work again in a separate control.

Code path

DocumentService dispatches task_func.delay(...) before redis_client.setex(..., 600, 1). The remove worker and add worker delete that key when finishing. A fast worker can therefore delete the key before the request recreates it.

Temporary workaround: wait for the lock to expire. This report establishes the defect on the tested commit; it does not claim that 1.18.0 introduced it.

Activity

  1. dosubot commented on Oct 23, 2026

    @dosubot

    Two additional cases are worth covering in the fix:

    • Archive/unarchive of enabled documents uses the same add/remove tasks and set_cache=True path, so it appears susceptible to the same race. Disabled documents skip task dispatch and cache creation for those actions. [1]
    • Task submission failure can also leave this guard behind: the service catches the .delay() exception, still executes setex, then re-raises the submission error. In that case, no successfully submitted worker is available to clear the key. [2]

    For regression coverage, simulating worker completion before .delay() returns would exercise the reported ordering deterministically, without relying on a fast local worker.

    To reply, just mention @dosu.


    Share context across your team and agents. Try Dosu.

    Leave Feedback Learn about dify with Dosu

  2. GYJ99 commented on Oct 23, 2026

    @GYJ99
    Contributor

    Hi, I'd be happy to take a focused backend fix for this indexing-cache race. I can add deterministic regression coverage for a worker that finishes before task dispatch returns, and for task submission failures, while checking the shared enable/disable and archive/unarchive paths. If no one is already working on this, could you assign #44598 to @GYJ99? Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions