zeroclaw-labs/zeroclaw · error

knowledge graph node limit reached ({}/{})

Error message

knowledge graph node limit reached ({}/{})

What it means

KnowledgeGraph is a SQLite-backed graph with a hard node capacity set at construction (KnowledgeGraph::new(db_path, max_nodes)). add_node first runs SELECT COUNT(*) FROM nodes and refuses the insert — before touching tags or writing — once the total reaches max_nodes, reporting (current, max). This is a deliberate bounding of graph growth (disk and FTS cost), not corruption: the call simply fails and nothing is written.

Source

Thrown at crates/zeroclaw-memory/src/knowledge_graph.rs:214

            max_nodes,
        })
    }

    /// Add a node to the graph. Returns the generated node id.
    pub fn add_node(
        &self,
        node_type: NodeType,
        title: &str,
        content: &str,
        tags: &[String],
        source_project: Option<&str>,
    ) -> anyhow::Result<String> {
        let conn = self.conn.lock();

        // Enforce max_nodes limit.
        let count: usize = conn.query_row("SELECT COUNT(*) FROM nodes", [], |r| r.get(0))?;
        if count >= self.max_nodes {
            anyhow::bail!(
                "knowledge graph node limit reached ({}/{})",
                count,
                self.max_nodes
            );
        }

        // Reject tags containing commas since comma is the separator in storage.
        for tag in tags {
            if tag.contains(',') {
                anyhow::bail!(
                    "tag '{}' contains a comma, which is used as the tag separator",
                    tag
                );
            }
        }

        let id = Uuid::new_v4().to_string();
        let now = Utc::now().to_rfc3339();

View on GitHub (pinned to 88bb9c8533)

Solutions

  1. Check the pair in the message: if the cap is simply too small for real use, open the graph with a larger max_nodes in KnowledgeGraph::new.
  2. Prune or consolidate stale nodes (old interactions, superseded lessons) to bring COUNT(*) below the limit, then retry.
  3. Before adding in bulk, read graph.stats()?.total_nodes and budget the import against max_nodes instead of failing mid-batch.
  4. If growth is the norm, schedule periodic pruning/archival so add_node never reaches the ceiling.

Example fix

// before
let graph = KnowledgeGraph::new(&path, 100)?;
// ... after 100 captures:
graph.add_node(NodeType::Lesson, "t", "c", &[], None)?; // node limit reached (100/100)

// after: size the cap to real usage and prune before imports
let graph = KnowledgeGraph::new(&path, 10_000)?;
if graph.stats()?.total_nodes + batch_len >= 10_000 { /* prune first */ }
Defensive patterns

Strategy: validation

Validate before calling

// Check headroom before writing
let stats = graph.stats()?;
if stats.total_nodes >= max_nodes {
    return Err(anyhow::anyhow!(
        "graph at capacity ({}/{}): prune before adding", stats.total_nodes, max_nodes
    ));
}
let id = graph.add_node(node_type, title, content, tags, source)?;

Try / catch

// In capture loops: capacity errors mean 'shed load', not 'crash'
match graph.add_node(node_type, title, content, tags, src) {
    Ok(id) => Some(id),
    Err(e) if e.to_string().contains("node limit reached") => {
        tracing::warn!(error = %e, "knowledge graph full; dropping capture");
        None
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling add_node (including via the capture handler) on a graph whose nodes table already has max_nodes or more rows. The count is over ALL node types, so heavy capture of one type (e.g. interactions) exhausts the budget for every other type. Also hit when the constructor was given a small max_nodes for testing and production data outgrew it.

Common situations: Long-running agents that capture knowledge every turn eventually fill the cap; a copied-to-production config with a tiny test limit; bulk-import scripts (migrating another graph) exceeding the ceiling mid-run; test suites asserting the limit (add_node tests).

Related errors


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