zeroclaw-labs/zeroclaw · error
notion.database_id must not be empty when notion.enabled = t
Error message
notion.database_id must not be empty when notion.enabled = true
What it means
Thrown by the whole-config validator (Config::validate) in zeroclaw-config when the [notion] section has enabled = true but database_id is empty after trimming. The Notion integration needs to know which database to poll, so an enabled integration without a target is treated as a configuration defect, not a runtime warning. It aborts config load before any Notion API call is made. Note that the same block also enforces poll_interval_secs > 0 via a typed validation_bail, so fix both when editing.
Source
Thrown at crates/zeroclaw-config/src/schema.rs:22011
match reqwest::Url::parse(®.url) {
Ok(u) if matches!(u.scheme(), "http" | "https" | "file") => {}
Ok(u) => anyhow::bail!(
"skills.extra_registries[{}].url scheme '{}' is unsupported (use http, https, or file)",
reg.name,
u.scheme()
),
Err(e) => anyhow::bail!(
"skills.extra_registries[{}].url is not a valid URL: {e}",
reg.name
),
}
}
}
// Notion
if self.notion.enabled {
if self.notion.database_id.trim().is_empty() {
anyhow::bail!("notion.database_id must not be empty when notion.enabled = true");
}
if self.notion.poll_interval_secs == 0 {
validation_bail!(
InvalidNumericRange,
"notion.poll_interval_secs",
"notion.poll_interval_secs must be greater than 0"
);
}
if self.notion.max_concurrent == 0 {
validation_bail!(
InvalidNumericRange,
"notion.max_concurrent",
"notion.max_concurrent must be greater than 0"
);
}
if self.notion.status_property.trim().is_empty() {
validation_bail!(
RequiredFieldEmpty,View on GitHub (pinned to 88bb9c8533)
Solutions
- Set notion.database_id to the 32-character Notion database id (from the database URL or via the Notion API integration page)
- Or set notion.enabled = false if the integration is not intended to run
- Ensure the value has no surrounding quotes-with-spaces; it is trimmed but must be non-empty
- Also set notion.poll_interval_secs to a value > 0 to clear the adjacent check in the same validation block
Example fix
# before [notion] enabled = true # database_id missing # after [notion] enabled = true database_id = "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4" poll_interval_secs = 300
Defensive patterns
Strategy: validation
Validate before calling
fn notion_config_ok(n: &NotionConfig) -> bool {
!n.enabled || (!n.database_id.trim().is_empty() && n.poll_interval_secs > 0)
}
// call before config load/save:
assert!(notion_config_ok(&cfg.notion), "fix [notion] before enabling"); Try / catch
match cfg.validate() {
Ok(()) => { /* proceed */ }
Err(e) if e.to_string().starts_with("notion.database_id") => {
eprintln!("Notion enabled without database_id — set it or disable notion");
return;
}
Err(e) => return Err(e),
} Prevention
- Treat enabled=true as a commitment: never flip it without also setting database_id
- Keep a validated example config in the repo and CI that runs cfg.validate() on every config change
- When templating configs, fail the template render if notion.enabled is true but the id placeholder was not substituted
When it happens
Trigger: Setting `notion.enabled = true` in config.toml while `notion.database_id` is absent, set to "", or set to a whitespace-only string; copying a template config that ships with an empty [notion] block and flipping only the enabled flag; disabling then re-enabling Notion after the database id was removed.
Common situations: User enables the Notion channel before creating/copying the database; config generated by a script or UI that writes enabled but not the id; migration from an older config where database_id lived under a different key and was dropped.
Understand the failure class
Background: Config validation failed: what "invalid value for {key}" and settings-rejection errors mean across 19 open-source libraries — this error's family across 19 libraries.
Related errors
- jira.base_url must not be empty when jira.enabled = true
- google_workspace.allowed_operations[{i}].resource must not b
- matrix: `homeserver` is required
- Cannot persist empty Telegram identity
- Missing [channels.telegram.{}] section. Run `zeroclaw config
AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23).
Data as JSON: /api/errors/0e495c24a5b1fcfb.
Report an issue: GitHub.