Skip to content

[Bug] memos-local-plugin: config validator reports schema-declared 'reasoning' keys as unknown on every boot (same class as #2247) #2474

Description

@chiefmojo

Summary

Every boot logs a false unknown config key warning for each LLM slot that sets reasoning:

config.warning message="unknown config key 'llm.reasoning' (kept as-is for forward compatibility)"
config.warning message="unknown config key 'skillEvolver.reasoning' (kept as-is …)"
config.warning message="unknown config key 'entityExtractor.reasoning' (kept as-is …)"
config.warning message="unknown config key 'l3Llm.reasoning' (kept as-is …)"

reasoning is a declared field (reasoning: Type.Optional(ReasoningSchema) in LlmSchema and SkillEvolverSchema, core/config/schema.ts), and it is applied: the value passes through to the request body. Only the warning is wrong.

This is the same class as #2247 (llm.maxTokens / llm.headers). #2248 fixed that one by adding those keys to DEFAULT_CONFIG, but reasoning was not covered, and core/config/defaults.ts on main still has no reasoning entry.

Cause

pruneUnknown(raw, DEFAULT_CONFIG, …) (core/config/index.ts) decides "unknown" by membership in the defaults object, not the schema. Any Type.Optional(...) field without a default is reported as unknown, so this will recur for every future optional key.

Why it matters

A warning that fires on every boot trains operators to ignore config.warning, and a real typo (reasonning, or a key removed from the schema) then gets lost in it.

Suggested fix

Prefer deriving the known keys from the TypeBox schema: walk Type.Object properties, recursing into nested objects, and keep FREE_FORM_CONFIG_PATHS as it is. That fixes reasoning and every future optional field at once. The lighter option, following #2248, is to add a reasoning default, but the request body must still omit it when it isn't configured.

Test idea

llm.reasoning: { enabled: false } produces no warning; llm.reasonning: {} still warns; the resolved config keeps reasoning unchanged.

Activity

  1. added
    ai:taskDispatched to AI coding agent | 已派发给 AI 编码任务
    status:in-progressSomeone or AI is working on it | 人工或 AI 正在处理
    types:bugSomething isn't working | 功能异常
    on Oct 8, 2026
  2. self-assigned this
    on Oct 8, 2026
  3. Memtensor-AI commented on Oct 8, 2026

    @Memtensor-AI
    Collaborator

    🤖 AutoDev has picked up this issue and started working on it.

    Task ID: 85e5733f87f42cdc
    Working branch: bugfix/autodev-2474-20261008202913915
    Target branch: latest dev* branch
    Workflow: opsp (analysis → coding → testing → PR)

    I will post the PR link here once done. If I need more information, I will ask in the comments.

  4. Memtensor-AI commented on Oct 8, 2026

    @Memtensor-AI
    Collaborator

    ✅ AutoDev task 85e5733f87f42cdc completed.

    Summary: Fixes #2474 — the memos-local-plugin config validator falsely reported schema-declared reasoning fields (llm.reasoning, skillEvolver.reasoning, l3Llm.reasoning) as unknown config keys on every boot. The root cause was pruneUnknown in apps/memos-local-plugin/core/config/index.ts using DEFAULT_CONFIG as the "known keys" oracle, which misses any Type.Optional(...) field without a concrete default — the same defect class as #2247/#2248.

    The fix rewrites pruneUnknown to walk the TypeBox ConfigSchema directly: it uses the properties map of type: "object" nodes to decide what is known, and treats patternProperties (TypeBox Type.Record) as a free-form map so llm.headers, logging.channels, and similar free-form sections continue to accept arbitrary child keys. The existing FREE_FORM_CONFIG_PATHS allowlist is preserved for backward compatibility. The warning text, pass-through semantics, and the downstream pipeline (deepMerge → Value.Default → Value.Errors) are all unchanged.

    Verification: a new tests/unit/config/schema-driven-unknown-keys.test.ts adds 9 regression cases (reasoning no-warning across all three LLM slots, typos still warn, Record-based free-form maps unchanged, nested unknowns inside a known Optional block still warn, resolved config retains the reasoning block byte-for-byte). Full plugin unit suite 1599 pass + 1 skipped, integration suite 6/6, tsc -p tsconfig.json --noEmit clean.

    Base branch: main
    Branch: bugfix/autodev-2474-20261008202913915
    Commit: 42427d5
    PR: #2475
    Assigned to: @syzsunshine219
    Reviewers: @whipser030, @hijzy

  5. added
    ai:testingAI agent is running tests | AI 正在运行测试
    ai:failedAI task failed | AI 任务失败
    and removed
    ai:codingAI agent is coding | AI 正在编码
    ai:testingAI agent is running tests | AI 正在运行测试
    ai:taskDispatched to AI coding agent | 已派发给 AI 编码任务
    on Oct 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

ai:failedAI task failed | AI 任务失败area:pluginOpenClaw & Hermesstatus:in-progressSomeone or AI is working on it | 人工或 AI 正在处理types:bugSomething isn't working | 功能异常

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions