windmill-labs/windmill · error

Database read failed: {e:?}

Error message

Database read failed: {e:?}

What it means

OSS agent memory reader: `read_from_memory` wraps any failure of `memory_common::read_from_db` (which loads prior OpenAI-format messages for an agent conversation step from the database). The `{e:?}` debug format exposes the full error chain. The agent run fails because conversation history could not be loaded.

Source

Thrown at backend/windmill-worker/src/memory_oss.rs:21

pub use crate::memory_ee::*;

#[cfg(not(all(feature = "private", feature = "enterprise")))]
use {
    crate::memory_common, uuid::Uuid, windmill_ai::types::OpenAIMessage, windmill_common::db::DB,
};

/// Read AI agent memory from storage
/// In OSS: always reads from database
#[cfg(not(all(feature = "private", feature = "enterprise")))]
pub async fn read_from_memory(
    db: &DB,
    workspace_id: &str,
    conversation_id: Uuid,
    step_id: &str,
) -> anyhow::Result<Option<Vec<OpenAIMessage>>> {
    memory_common::read_from_db(db, workspace_id, conversation_id, step_id)
        .await
        .map_err(|e| anyhow::anyhow!("Database read failed: {e:?}"))
}

/// Write AI agent memory to storage
/// In OSS: always writes to database
#[cfg(not(all(feature = "private", feature = "enterprise")))]
pub async fn write_to_memory(
    db: &DB,
    workspace_id: &str,
    conversation_id: Uuid,
    step_id: &str,
    messages: &[OpenAIMessage],
) -> anyhow::Result<()> {
    if messages.is_empty() {
        return Ok(());
    }

    memory_common::write_to_db(db, workspace_id, conversation_id, step_id, messages)
        .await

View on GitHub (pinned to e474e8803c)

Solutions

  1. Read the `{e:?}` chain in the job error to identify the root cause (connection vs. relation-missing vs. deserialization).
  2. Run pending Windmill database migrations so the memory tables exist.
  3. Verify DATABASE_URL connectivity from the worker.
  4. If deserialization fails, delete the corrupted conversation memory rows and re-run the agent step.
Defensive patterns

Strategy: try-catch

Validate before calling

// verify memory tables exist before running agents
psql "$DATABASE_URL" -c '\d agent_memory' || echo 'run migrations first'

Try / catch

match read_from_memory(&db, w_id, conv_id, &step_id).await {
    Ok(msgs) => msgs,
    Err(e) => { log::warn!("memory read failed, starting fresh: {e:?}"); None }
}

Prevention

When it happens

Trigger: `run_agent` starting a new step calls `read_from_memory(db, workspace_id, conversation_id, step_id)`; the underlying DB query fails — connection drop, table missing (pre-migration database), or the row/tuple shape can't be deserialized into `Vec<OpenAIMessage>`.

Common situations: Self-hosted OSS instance upgraded without running migrations (memory tables absent); Postgres briefly unavailable; corrupted JSON stored in the memory column from an older schema version.

Related errors


AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03). Data as JSON: /api/errors/ad5b05df5d7774a7. Report an issue: GitHub.