datawhalechina/hello-agents · warning · HTTPException

无效的分类: {request.category},有效值: {valid_categories}

Error message

无效的分类: {request.category},有效值: {valid_categories}

What it means

Raised by POST /api/memory/capture when request.category is not one of the four allowed strings: preference, decision, entity, fact. The whitelist is hardcoded in the route (not in the Pydantic model), so any other value — including differently-cased forms — is rejected with HTTP 400 listing the valid values.

Source

Thrown at Co-creation-projects/tino-chen-HelloClaw/src/api/memory.py:196


@router.post("/today")
async def add_to_today(content: str, ws: WorkspaceManager = Depends(get_workspace)):
    """添加内容到今日记忆"""
    ws.append_to_daily_memory(content)
    return {"status": "ok", "message": "已添加到今日记忆"}


@router.post("/capture", response_model=MemoryCaptureResponse)
async def capture_memory(
    request: MemoryCaptureRequest,
    ws: WorkspaceManager = Depends(get_workspace)
):
    """手动添加记忆(带分类)"""
    # 验证分类
    valid_categories = ["preference", "decision", "entity", "fact"]
    if request.category not in valid_categories:
        raise HTTPException(
            status_code=400,
            detail=f"无效的分类: {request.category},有效值: {valid_categories}"
        )

    # 检查重复
    if ws.check_duplicate_memory(request.content, threshold=0.7):
        return MemoryCaptureResponse(
            status="skipped",
            message="记忆已存在,跳过",
            category=request.category
        )

    # 存储记忆
    ws.append_classified_memory(request.content, request.category)

    return MemoryCaptureResponse(
        status="ok",
        message=f"已添加 [{request.category}] 记忆",

View on GitHub (pinned to 606a07d341)

Solutions

  1. Send one of exactly: preference, decision, entity, fact — all lowercase
  2. Constrain the client field to a closed enum so invalid values cannot be constructed
  3. If a new category is genuinely needed, extend the valid_categories list in memory.py (server change)

Example fix

// before
body = {content: "...", category: "Preference"}
// after
const CATEGORIES = ['preference','decision','entity','fact'];
body = {content: "...", category: CATEGORIES.includes(category) ? category : 'fact'}
Defensive patterns

Strategy: validation

Validate before calling

const VALID = new Set(['preference', 'decision', 'entity', 'fact']);
const category = VALID.has(raw) ? raw : null;
if (!category) throw new Error(`Invalid category: ${raw}`);

Type guard

const isMemoryCategory = (v: string): v is 'preference'|'decision'|'entity'|'fact' =>
  ['preference','decision','entity','fact'].includes(v);

Prevention

When it happens

Trigger: POST /api/memory/capture with category 'Preference' (capitalized), 'note', 'idea', 'snippet', or a null/omitted category field.

Common situations: Client UI dropdown that grew new categories without updating the API whitelist; enum serialized as 'MemoryCategory.preference' instead of the bare value; copy-pasted category names from other tools (Notion/Readwise tags).

Related errors


AI-assisted analysis of datawhalechina/hello-agents@606a07d341 (2026-08-14). Data as JSON: /api/errors/67b8a410fc3e7981. Report an issue: GitHub.