lfnovo/open-notebook · error · HTTPException

Item type must be either 'source' or 'note'

Error message

Item type must be either 'source' or 'note'

What it means

400 from POST /api/embed rejecting an unsupported item_type. The endpoint only embeds two item kinds — 'source' and 'note' — and lowercases the input before checking, so anything else ('document', 'chat', 'Note ' with trailing junk, etc.) fails this validation.

Source

Thrown at api/routers/embedding.py:32


@router.post("/embed", response_model=EmbedResponse)
async def embed_content(embed_request: EmbedRequest):
    """Embed content for vector search."""
    try:
        # Check if embedding model is available
        if not await model_manager.get_embedding_model():
            raise HTTPException(
                status_code=400,
                detail="No embedding model configured. Please configure one in the Models section.",
            )

        item_id = embed_request.item_id
        item_type = embed_request.item_type.lower()

        # Validate item type
        if item_type not in ["source", "note"]:
            raise HTTPException(
                status_code=400, detail="Item type must be either 'source' or 'note'"
            )

        # Branch based on processing mode
        if embed_request.async_processing:
            # ASYNC PATH: Submit command for background processing
            logger.info(f"Using async processing for {item_type} {item_id}")

            try:
                # Import commands to ensure they're registered
                import commands.embedding_commands  # noqa: F401

                # Submit type-specific command
                if item_type == "source":
                    command_name = "embed_source"
                    command_input = {"source_id": item_id}
                else:  # note
                    command_name = "embed_note"

View on GitHub (pinned to a7de90d38a)

Solutions

  1. Change item_type to exactly 'source' or 'note' (case-insensitive)
  2. Check the EmbedRequest schema/client SDK for the accepted enum values
  3. If you need to embed a different entity type, find or create its dedicated endpoint instead

Example fix

// before
{"item_id": "...", "item_type": "document", "async_processing": true}
// after
{"item_id": "...", "item_type": "source", "async_processing": true}
Defensive patterns

Strategy: type-guard

Validate before calling

const ITEM_TYPES = ['source', 'note'];
if (!ITEM_TYPES.includes(embedRequest.item_type.toLowerCase())) throw new Error(`item_type must be one of ${ITEM_TYPES}`);

Type guard

function isEmbedItemType(v: string): v is 'source' | 'note' {
  return v === 'source' || v === 'note';
}

Try / catch

try {
  await api.embed(payload);
} catch (e) {
  if (e.status === 400 && /item type/i.test(e.detail)) fixItemType(payload);
  throw e;
}

Prevention

When it happens

Trigger: POST /api/embed with item_type: 'chunk', 'document', 'conversation', or a misspelled value like 'sourse'. The check happens after .lower(), so case is fine but the string must be exactly 'source' or 'note'.

Common situations: Client code written against a different API version or assumed vocabulary, typos in integrations/scripts, or passing a database table name instead of the item type.

Related errors


AI-assisted analysis of lfnovo/open-notebook@a7de90d38a (2026-08-27). Data as JSON: /api/errors/f726351238fadff1. Report an issue: GitHub.