zeroclaw-labs/zeroclaw · error

{field_name} must not be empty

Error message

{field_name} must not be empty

What it means

validate_identifier guards PostgreSQL identifiers (schema and table names) that are interpolated directly into SQL text. This first check fires when the identifier string is empty — a required name was never set. The function is called from the store constructor (new) and validated_schema_identifier, so it typically surfaces at backend creation time.

Source

Thrown at crates/zeroclaw-memory/src/postgres.rs:333

            let result = f();
            let _ = tx.send(result);
        })
        .context("failed to spawn PostgreSQL operation thread")?;

    rx.await.map_err(|_| {
        ::zeroclaw_log::record!(
            ERROR,
            ::zeroclaw_log::Event::new(module_path!(), ::zeroclaw_log::Action::Fail)
                .with_outcome(::zeroclaw_log::EventOutcome::Failure),
            "PostgreSQL operation thread terminated unexpectedly"
        );
        anyhow::Error::msg("PostgreSQL operation thread terminated unexpectedly")
    })?
}

pub(super) fn validate_identifier(value: &str, field_name: &str) -> Result<()> {
    if value.is_empty() {
        anyhow::bail!("{field_name} must not be empty");
    }

    let mut chars = value.chars();
    let Some(first) = chars.next() else {
        anyhow::bail!("{field_name} must not be empty");
    };

    if !(first.is_ascii_alphabetic() || first == '_') {
        anyhow::bail!("{field_name} must start with an ASCII letter or underscore; got '{value}'");
    }

    if !chars.all(|ch| ch.is_ascii_alphanumeric() || ch == '_') {
        anyhow::bail!(
            "{field_name} can only contain ASCII letters, numbers, and underscores; got '{value}'"
        );
    }

    Ok(())

View on GitHub (pinned to 88bb9c8533)

Solutions

  1. Set the missing schema/table identifier in `[storage.postgres.<alias>]`.
  2. If deriving identifiers from agent or storage aliases, apply a sanitizer that falls back to a default when the result is empty.

Example fix

# before
[storage.postgres.main]
schema = ""

# after
[storage.postgres.main]
schema = "zeroclaw"
Defensive patterns

Strategy: validation

Validate before calling

let pg = &config.storage.postgres[alias];
if pg.schema.as_deref().unwrap_or("").trim().is_empty()
    || pg.table.as_deref().unwrap_or("").trim().is_empty()
{
    anyhow::bail!("postgres storage alias '{alias}' is missing a schema or table name");
}

Prevention

When it happens

Trigger: Constructing the postgres memory store with an empty schema or table identifier: a defaulted config field left blank (schema = "" in [storage.postgres.<alias>]), or an identifier derived from an alias that sanitizes down to the empty string.

Common situations: Optional storage config fields left empty in TOML; alias-derived identifiers where the alias consists only of characters that get stripped; programmatic construction passing an unpopulated struct field.

Related errors


AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23). Data as JSON: /api/errors/f1bf9381acb1eb85. Report an issue: GitHub.