langgenius/dify · error · InvalidActionError

invalid_action

invalid_action

Error message

Document not in indexing state.

What it means

HTTP 400, error_code invalid_action, raised by the processing pause/resume handler when action="pause" but document.indexing_status != IndexingStatus.INDEXING (datasets_document.py:1249). Pause is only meaningful while indexing is actively running.

Source

Thrown at api/controllers/console/datasets/datasets_document.py:1250

        session: Session,
        current_tenant_id: str,
        current_user: Account,
        dataset_id: UUID,
        document_id: UUID,
        action: Literal["pause", "resume"],
    ):
        dataset_id_str = str(dataset_id)
        document_id_str = str(document_id)
        document = self.get_document(session, dataset_id_str, document_id_str, current_user, current_tenant_id)

        # The role of the current user in the ta table must be admin, owner, dataset_operator, or editor
        if not current_user.is_dataset_editor:
            raise Forbidden()

        match action:
            case "pause":
                if document.indexing_status != IndexingStatus.INDEXING:
                    raise InvalidActionError("Document not in indexing state.")

                document.paused_by = current_user.id
                document.paused_at = naive_utc_now()
                document.is_paused = True

            case "resume":
                if document.indexing_status not in {IndexingStatus.PAUSED, IndexingStatus.ERROR}:
                    raise InvalidActionError("Document not in paused or error state.")

                document.paused_by = None
                document.paused_at = None
                document.is_paused = False

        return SimpleResultResponse(result="success").model_dump(mode="json"), 200


@console_ns.route("/datasets/<uuid:dataset_id>/documents/<uuid:document_id>/metadata")
class DocumentMetadataApi(DocumentResource):

View on GitHub (pinned to ef8544b173)

Solutions

  1. Check the document's indexing_status via the indexing-status endpoint before pausing.
  2. Only call pause when status is INDEXING.
  3. If the document errored, call resume instead (resume accepts ERROR).
Defensive patterns

Strategy: validation

Validate before calling

# Pre-flight: only pause a document actively indexing
status = console.get_document_indexing_status(dataset_id, document_id)
if status["indexing_status"] != "indexing":
    raise RuntimeError(f"Cannot pause: status is {status['indexing_status']}, expected 'indexing'.")

Type guard

def is_pauseable(status: dict) -> bool:
    return status.get("indexing_status") == "indexing"

Try / catch

try:
    console.process_document(dataset_id, document_id, action="pause")
except HTTPError as e:
    if e.response.status_code == 400 and e.response.json().get("code") == "invalid_action":
        # refresh status; document may have already left INDEXING
        refresh_document_status(document_id)
    else:
        raise

Prevention

When it happens

Trigger: PATCH .../processing/pause on a document whose status is waiting, parsing, completed, error, or already paused; the match arm rejects it.

Common situations: UI pause button enabled for a stale status; double pause click; pausing a document that already errored.

Related errors


AI-assisted analysis of langgenius/dify@ef8544b173 (2026-08-12). Data as JSON: /api/errors/e9e605349909d1c7. Report an issue: GitHub.