Summary
In plugin v2.0.17, l3.abstraction throws LLM_OUTPUT_MALFORMED: 'title' must be a non-empty string whenever the abstraction LLM call returns an empty/whitespace title. This aborts the entire world-model generation for that cluster — no retry, no fallback title, no skip-and-continue — so a single malformed LLM response kills the whole run.
Location
dist/core/memory/l3/abstract.js (v2.0.17), line ~56:
throw new MemosError(ERROR_CODES.LLM_OUTPUT_MALFORMED, "l3.abstraction: 'title' must be a non-empty string", { got: o.title });
Observed behavior (production evidence)
From api_logs in our deployment (Hermes adapter, Windows, openai_compatible LLM):
| Period |
Attempts |
Failures |
Dominant failure |
| 2.0.14 era (Aug 10–30) |
~2000 |
~1990 |
mostly host handler queue is full (separate issue) |
| 2.0.17 (Aug 30 → Sep 3) |
12 |
1 |
'title' must be a non-empty string |
Sample failure event:
{"kind":"l3.failed","stage":"abstract","error":{"code":"llm_failed","message":"l3.abstraction: 'title' must be a non-empty string"},"clusterKey":"python|_"}
The feature demonstrably works when the LLM behaves (6 world models successfully created since Aug 11), but the empty-title case turns one bad sample into a full pipeline failure.
Suggested fix
Instead of throwing on empty title:
- Retry once with a repair prompt ("return JSON with a non-empty title"), or
- Derive a fallback title (e.g. join
domainTags, or first line of the body), and only skip storing that one model — never fail the whole abstraction stage.
Note: dist/core/memory/l2/induce.js:54 has the same throw-on-malformed pattern for multiple fields; the same hardening may be worth applying there.
Environment
- memos-local plugin 2.0.17 (npm
memtensor-memos-local-plugin-2.0.17)
- Adapter: Hermes (
adapters/hermes/memos_provider)
- Windows 11, Node v24, LLM provider
openai_compatible (deepseek-family via local gateway)
Summary
In plugin v2.0.17,
l3.abstractionthrowsLLM_OUTPUT_MALFORMED: 'title' must be a non-empty stringwhenever the abstraction LLM call returns an empty/whitespacetitle. This aborts the entire world-model generation for that cluster — no retry, no fallback title, no skip-and-continue — so a single malformed LLM response kills the whole run.Location
dist/core/memory/l3/abstract.js(v2.0.17), line ~56:Observed behavior (production evidence)
From
api_logsin our deployment (Hermes adapter, Windows, openai_compatible LLM):host handler queue is full(separate issue)'title' must be a non-empty stringSample failure event:
{"kind":"l3.failed","stage":"abstract","error":{"code":"llm_failed","message":"l3.abstraction: 'title' must be a non-empty string"},"clusterKey":"python|_"}The feature demonstrably works when the LLM behaves (6 world models successfully created since Aug 11), but the empty-title case turns one bad sample into a full pipeline failure.
Suggested fix
Instead of throwing on empty
title:domainTags, or first line of the body), and only skip storing that one model — never fail the whole abstraction stage.Note:
dist/core/memory/l2/induce.js:54has the same throw-on-malformed pattern for multiple fields; the same hardening may be worth applying there.Environment
memtensor-memos-local-plugin-2.0.17)adapters/hermes/memos_provider)openai_compatible(deepseek-family via local gateway)