affaan-m/ECC · error · anyhow::Error

page_size must be greater than 0

Error message

page_size must be greater than 0

What it means

The observability tool-log query API validates pagination input and rejects `page_size == 0`, since a zero page size cannot return any rows and would produce an empty/meaningless page. The public `query` method bails immediately before delegating to the database layer.

Solutions

  1. Pass a page_size >= 1, e.g. use a sensible default like 20 or 50.
  2. Clamp the caller-supplied page size: `page_size.max(1)` before calling `query`.
  3. Fix the config default so unset page size falls back to a positive constant instead of 0.
  4. Note the implementation itself clamps `page` to at least 1 — only `page_size` must be sanitized by the caller.

Example fix

// before
let page = store.query(&session_id, 1, config.page_size); // page_size defaults to 0
// after
let page = store.query(&session_id, 1, config.page_size.max(1).min(100));
Defensive patterns

Strategy: validation

Validate before calling

fn sanitize_page_size(raw: u64) -> u64 {
    raw.clamp(1, 100)
}

Type guard

fn is_valid_page_size(n: u64) -> bool { n > 0 }

Try / catch

match store.query(&session_id, page, page_size) {
    Err(e) if e.to_string().contains("page_size must be greater than 0") => {
        let page = store.query(&session_id, page, DEFAULT_PAGE_SIZE)?;
    }
    other => other?,
}

Prevention

When it happens

Trigger: Calling `ToolLogStore::query(session_id, page, 0)`; UI or API layer computing page_size from an unset config defaulting to 0; a client sending `page_size=0` in a query parameter parsed straight into u64.

Common situations: Optional config `page_size` left unset and destructured with `unwrap_or(0)`; user submitting a form/page-size input with 0 or blank that parses to 0; pagination loop that decrements to 0.

Understand the failure class

Background: "Invalid query parameter" / "Failed to parse value of ...": fixing bad query string parameters across APIs — this error's family across 36 libraries.

Related errors


AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16). Data as JSON: /api/errors/5e6fc4933f450a2d. Report an issue: GitHub.

Appendix: source

Thrown at ecc2/src/observability/mod.rs:288

    pub fn log(&self, event: &ToolCallEvent) -> Result<ToolLogEntry> {
        let timestamp = chrono::Utc::now().to_rfc3339();

        self.db.insert_tool_log(
            &event.session_id,
            &event.tool_name,
            &event.input_summary,
            &event.input_params_json,
            &event.output_summary,
            &event.trigger_summary,
            event.duration_ms,
            event.risk_score,
            &timestamp,
        )
    }

    pub fn query(&self, session_id: &str, page: u64, page_size: u64) -> Result<ToolLogPage> {
        if page_size == 0 {
            bail!("page_size must be greater than 0");
        }

        self.db.query_tool_logs(session_id, page.max(1), page_size)
    }
}

pub fn log_tool_call(db: &StateStore, event: &ToolCallEvent) -> Result<ToolLogEntry> {
    ToolLogger::new(db).log(event)
}

#[cfg(test)]
mod tests {
    use super::{SuggestedAction, ToolCallEvent, ToolLogger};
    use crate::config::Config;
    use crate::session::store::StateStore;
    use crate::session::{Session, SessionMetrics, SessionState};
    use std::path::PathBuf;

View on GitHub (pinned to 8321021c54)