TencentCloud/TencentDB-Agent-Memory · error

[sqlite] deleteL0BySession requires a non-empty sessionId

Error message

[sqlite] deleteL0BySession requires a non-empty sessionId

What it means

deleteL0BySession refuses empty session IDs because an empty sessionId would match legacy rows with empty session_key/session_id, deleting far more data than intended. The guard trims the input and rejects empty results to prevent accidental mass deletion.

Source

Thrown at MemoryCore/src/core/store/sqlite.ts:2687

      const rows = this.db.prepare(dataSql).all(...params, filter.limit, filter.offset) as unknown as L1RecordRow[];

      return { rows, total };
    } catch (err) {
      this.logger?.warn(`[sqlite] queryL1Paginated failed: ${err instanceof Error ? err.message : String(err)}`);
      return { rows: [], total: 0 };
    }
  }

  /**
   * Delete all L0 messages belonging to a session.
   * Returns the count of actually deleted rows.
   */
  deleteL0BySession(sessionId: string, filter?: IsolationFilter): number {
    // 空 sessionId 会匹配所有 session_key/session_id 为空的历史 legacy 行,
    // 造成远超预期的删除范围。空 session 不是有效删除目标,直接拒绝。
    const sessionIdTrimmed = (sessionId ?? "").trim();
    if (!sessionIdTrimmed) {
      throw new Error("[sqlite] deleteL0BySession requires a non-empty sessionId");
    }

    if (this.degraded) return 0;

    try {
      // 必须把 rowMatchesIsolation 会检查的**所有**列都取出来
      // (team_id / task_id 早期漏取,导致带 teamId 的 isolation filter
      // 永远判不匹配 → 按session 删除恒返回 0)。
      const rows = this.db.prepare(
        "SELECT record_id, session_key, session_id, team_id, task_id, user_id, agent_id FROM l0_conversations WHERE session_key = ? OR session_id = ?"
      ).all(sessionIdTrimmed, sessionIdTrimmed) as Array<{
        record_id: string; session_key: string; session_id: string;
        team_id: string; task_id: string; user_id: string; agent_id: string;
      }>;

      if (rows.length === 0) return 0;

      this.db.exec("BEGIN");

View on GitHub (pinned to 3efcd317b8)

Solutions

  1. Obtain a valid sessionId from the session/message object before calling deleteL0BySession
  2. Validate non-empty sessionId in your own code before invoking the API
  3. If the goal is to clear all rows, use an explicit purge/clear API rather than passing an empty sessionId

Example fix

// before
store.deleteL0BySession(msg.sessionId ?? '');
// after
if (msg.sessionId && msg.sessionId.trim()) {
  store.deleteL0BySession(msg.sessionId);
}
Defensive patterns

Strategy: validation

Validate before calling

function assertSessionId(id) {
  const t = (id ?? '').trim();
  if (!t) throw new Error('sessionId required for deleteL0BySession');
  return t;
}
store.deleteL0BySession(assertSessionId(msg.sessionId));

Type guard

function hasSessionId(v): v is string {
  return typeof v === 'string' && v.trim().length > 0;
}

Try / catch

try {
  store.deleteL0BySession(sessionId);
} catch (e) {
  if (String(e.message).includes('non-empty sessionId')) {
    logger.warn(`Skipped L0 delete: sessionId missing for message`);
    return 0;
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling VectorStore.deleteL0BySession(sessionId) with undefined, null, '', or a whitespace-only sessionId.

Common situations: Session ID lookup returning undefined before the delete call, a message object lacking session metadata, or string interpolation of an unset variable producing ''.

Related errors


AI-assisted analysis of TencentCloud/TencentDB-Agent-Memory@3efcd317b8 (2026-09-01). Data as JSON: /api/errors/eed58bd1002a967a. Report an issue: GitHub.