langgenius/dify · error · InvalidMetadataError

invalid_metadata

invalid_metadata

Error message

Invalid metadata value: {metadata}

What it means

Raised by GET /console/api/datasets/{dataset_id}/documents/{document_id} when the `metadata` query parameter is not one of the allowed METADATA_CHOICES {all, only, without} (datasets_document.py:1027). The offending value is interpolated into the message. HTTP 400, error_code invalid_metadata.

Source

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

        }
    )
    @console_ns.response(200, "Document retrieved successfully", console_ns.models[DocumentDetailResponse.__name__])
    @console_ns.response(404, "Document not found")
    @setup_required
    @login_required
    @account_initialization_required
    @with_current_user
    @with_current_tenant_id
    @rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_CREATE_AND_MANAGEMENT)
    @with_session(write=False)
    def get(self, session: Session, current_tenant_id: str, current_user: Account, dataset_id: UUID, document_id: UUID):
        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)

        metadata = request.args.get("metadata", "all")
        if metadata not in self.METADATA_CHOICES:
            raise InvalidMetadataError(f"Invalid metadata value: {metadata}")

        metadata_fields = {"doc_type", "doc_metadata"}
        if metadata == "only":
            response = DocumentDetailResponse.model_validate(
                {
                    "id": document.id,
                    "doc_type": document.doc_type,
                    "doc_metadata": document.get_doc_metadata_details(session=session),
                }
            )
            return response.model_dump(mode="json", include={"id", *metadata_fields}, exclude_unset=True), 200

        dataset_process_rules = DatasetService.get_process_rules(dataset_id_str, session)
        document_process_rule = document.get_dataset_process_rule(session=session)
        document_process_rules: Mapping[str, Any] = document_process_rule.to_dict() if document_process_rule else {}
        segment_count = document.get_segment_count(session=session)
        response = DocumentDetailResponse.model_validate(
            {

View on GitHub (pinned to ef8544b173)

Solutions

  1. Use one of the accepted values: all (default), only, or without.
  2. Send metadata=only to get just doc_type/doc_metadata, or metadata=without to omit them.
  3. If calling from an SDK, pin the SDK version to match the backend's METADATA_CHOICES.

Example fix

// before
GET /console/api/datasets/{ds}/documents/{doc}?metadata=full
// after
GET /console/api/datasets/{ds}/documents/{doc}?metadata=only
Defensive patterns

Strategy: validation

Validate before calling

ALLOWED_METADATA = {"all", "only", "without"}
metadata_param = requested or "all"
if metadata_param not in ALLOWED_METADATA:
    raise ValueError(f"metadata must be one of {ALLOWED_METADATA}, got {metadata_param!r}")
# then: GET .../documents/{id}?metadata={metadata_param}

Type guard

def is_valid_metadata_param(value: str) -> bool:
    return value in {"all", "only", "without"}

Try / catch

try:
    doc = console.get_document(dataset_id, document_id, metadata=metadata_param)
except HTTPError as e:
    if e.response.status_code == 400 and e.response.json().get("code") == "invalid_metadata":
        metadata_param = "all"  # fall back to default
        doc = console.get_document(dataset_id, document_id, metadata=metadata_param)
    else:
        raise

Prevention

When it happens

Trigger: GET .../documents/{id}?metadata=full, ?metadata=1, ?metadata=true, or any token outside the allowed set; the check at datasets_document.py:1053 rejects it.

Common situations: Frontend sending a localized or typo'd value; an SDK built against a different Dify version passing a new token; manual API call with a truncated or uppercased value.

Related errors


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