tinyhumansai/openhuman · error

OpenClaw memories table found but no content-like column was

Error message

OpenClaw memories table found but no content-like column was detected

What it means

The OpenClaw sqlite importer introspects the source `memory/brain.db`: key and category columns are picked with fallbacks, but the content column must be one of `content`, `value`, `text`, or `memory` (`pick_optional_column_expr`). If a `memories` table exists yet has none of those columns, the migration bails — the schema is not one it can safely map text out of.

Source

Thrown at src/openhuman/config/migration_helpers/core.rs:175

    let table_exists: Option<String> = conn
        .query_row(
            "SELECT name FROM sqlite_master WHERE type='table' AND name='memories' LIMIT 1",
            [],
            |row| row.get(0),
        )
        .optional()?;

    if table_exists.is_none() {
        return Ok(Vec::new());
    }

    let columns = table_columns(&conn, "memories")?;
    let key_expr = pick_column_expr(&columns, &["key", "id", "name"], "CAST(rowid AS TEXT)");
    let Some(content_expr) =
        pick_optional_column_expr(&columns, &["content", "value", "text", "memory"])
    else {
        bail!("OpenClaw memories table found but no content-like column was detected");
    };
    let category_expr = pick_column_expr(&columns, &["category", "kind", "type"], "'core'");

    let sql = format!(
        "SELECT {key_expr} AS key, {content_expr} AS content, {category_expr} AS category FROM memories"
    );

    let mut stmt = conn.prepare(&sql)?;
    let mut rows = stmt.query([])?;

    let mut entries = Vec::new();
    let mut idx = 0_usize;

    while let Some(row) = rows.next()? {
        let key: String = row
            .get(0)
            .unwrap_or_else(|_| format!("openclaw_sqlite_{idx}"));
        let content: String = row.get(1).unwrap_or_default();

View on GitHub (pinned to 7491200858)

Solutions

  1. Inspect the schema (`sqlite3 brain.db "PRAGMA table_info(memories);"`) and confirm one of content/value/text/memory exists.
  2. If the payload column is named differently, rename it (`ALTER TABLE memories RENAME COLUMN body TO content;`) or create a view aliasing it to a recognized name, then re-run the migration.
  3. If the db is not genuine OpenClaw data, point the migration at a valid OpenClaw workspace instead.

Example fix

-- before: memories table has payload in `body`
-- migration bails: no content-like column

-- after: alias the column into a recognized name
CREATE VIEW memories_importable AS
  SELECT key AS key, body AS content, category FROM memories;
-- (or) ALTER TABLE memories RENAME COLUMN body TO content;
Defensive patterns

Strategy: validation

Validate before calling

// Check the memories table exposes a content-like column before migrating
let cols: Vec<String> = conn
    .prepare("PRAGMA table_info(memories)")?
    .query_map([], |r| r.get::<_, String>(1))?
    .collect::<Result<_, _>>()?;
let has_content = ["content", "value", "text", "memory"]
    .iter()
    .any(|c| cols.iter().any(|x| x.eq_ignore_ascii_case(c)));
if !has_content {
    // skip the db import and surface a warning instead of failing the migration
}

Prevention

When it happens

Trigger: A source brain.db whose `memories` table stores its payload under a different column name — schema drift from another OpenClaw version, a user-built or third-party-generated database, or a table restored from a partial dump with renamed columns.

Common situations: Version drift between OpenClaw releases; hand-maintained databases; sqlite files produced by export tools that renamed columns.

Related errors


AI-assisted analysis of tinyhumansai/openhuman@7491200858 (2026-08-17). Data as JSON: /api/errors/42b93e02f03168f4. Report an issue: GitHub.