Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

Client timeout + retry can duplicate memcells for identical session/messages payload

オープン
#274 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 1 日以内に返信

まだ誰も着手していません。

評価

難易度
5/5
見積もり時間
1週間以上
初心者へのやさしさ
35/100
issue の種類
バグ
明瞭さ
おおむね明確
活発さ
静か
技術スタック
python, sqlite
領域
api, database

調査の方向性

Start by tracing /api/v1/memory/add and /api/v1/memory/flush, then inspect how the buffer merge path consumes messages and creates rows in the SQLite memcell table. Decide how retries should be identified and handled, including what happens when a key is reused with a different payload. Done means a retry cannot create duplicate memcells or downstream Markdown and search results, and the behavior is covered by tests.

索引モデルが issue の本文から書いたものです。

説明

Summary

When a client times out on /api/v1/memory/add or /api/v1/memory/flush, the server may continue processing in the background. If the client then retries the same session_id with the identical messages payload, EverOS can create duplicate memcell rows with the same message_ids_json but different memcell_id values.

Those duplicate memcells can later propagate into Markdown and search results.

Environment

  • EverOS version: 1.0.0
  • Runtime: Linux container
  • Memorize mode: chat
  • Memory root: isolated test memory root
  • Sample data: synthetic text only

No real user memory was used.

Why this matters

Clients cannot safely treat timeout as failure. A timed-out request may still generate memcells, Markdown files, cascade updates, and searchable rows. If the client blindly retries the same payload, the memory store can be polluted with duplicate memories.

This is especially risky for agent memory integrations, where callers often retry on HTTP timeout.

Reproduction Outline

Use an isolated memory root and synthetic messages.

  1. Start EverOS server in chat mode.
  2. Send /api/v1/memory/add with a short client timeout.
  3. Send /api/v1/memory/flush with a short client timeout.
  4. Without auditing backend state, retry the same /add payload:
    • same app_id
    • same project_id
    • same session_id
    • same messages
    • same timestamps
  5. Retry /flush.
  6. Inspect SQLite memcell.
  7. Wait for background extraction / cascade to finish.
  8. Inspect Markdown and search results.

Synthetic Payload Shape

Example payload shape:

{
  "session_id": "retry_probe_001",
  "app_id": "test_app",
  "project_id": "retry_audit",
  "messages": [
    {
      "sender_id": "test_user",
      "sender_name": "Test User",
      "role": "user",
      "timestamp": 1780870000000,
      "content": "Remember exactly: retry-token-mu equals audit-mu-772."
    },
    {
      "sender_id": "test_assistant",
      "sender_name": "Test Assistant",
      "role": "assistant",
      "timestamp": 1780870000500,
      "content": "Acknowledged. I will preserve the exact retry audit token."
    }
  ]
}

Observed Behavior

After retrying the same payload, SQLite contained two memcell rows for the same session.

Both rows had the same message_ids_json, but different memcell_id values.

Example observed shape:

memcell_id: mc_<first>
message_ids_json:
  ["m_retry_probe_001_1780870000000_000", "m_retry_probe_001_1780870000500_001"]

memcell_id: mc_<second>
message_ids_json:
  ["m_retry_probe_001_1780870000000_000", "m_retry_probe_001_1780870000500_001"]

After background processing completed:

  • Markdown contained repeated references to the same synthetic marker.
  • Search returned duplicate episode results for the same synthetic marker.

Expected Behavior

EverOS should provide retry-safe behavior for timed-out clients.

Possible acceptable fixes:

  • Support an idempotency_key or client_request_id on /add.
  • Expose request/session processing status so clients can audit before retrying.
  • Prevent duplicate memcell creation for the same app_id, project_id, session_id, track, and message_ids_json.
  • Document safe retry behavior for /add and /flush.

Current Code Observation

The input message IDs appear deterministic for the same session_id, timestamp, and message index.

However, memcell_id is minted independently for each boundary result. The memcell table uses memcell_id as primary key and does not appear to enforce uniqueness on:

app_id + project_id + session_id + track + message_ids_json

The buffer merge path deduplicates by message_id, but once messages have been consumed into a memcell and the buffer is cleared, replaying the same payload can create a new memcell.

Suggested Direction

The safest contract would be API-level idempotency:

  • Client supplies an idempotency_key.
  • EverOS stores key + payload hash + processing status + result.
  • Retrying the same key returns the original result or current processing state.
  • Same key with different payload returns a conflict error.

A lower-level safety net would be to prevent duplicate memcells for the same scoped message_ids_json, but that alone may not fully solve HTTP retry semantics.

主要言語
Python
スター
13.3k
フォーク
926
平均マージ
17時間 40分
マージ済み PR(30日)
31

環境構築

このプロジェクトには開発コンテナ、Dockerfile、コントリビューションガイドがありません。まず README を読み、一般的な手順ははじめてのコントリビューションガイドを参照してください。

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

EverMind-AI/EverOS のほかの issue

EverMind-AI/EverOS の issue をすべて見る

似ている issue

Python の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。