{"record":{"id":"0e495c24a5b1fcfb","repo":"zeroclaw-labs/zeroclaw","slug":"notion-database-id-must-not-be-empty-when-notion-e","errorCode":null,"errorMessage":"notion.database_id must not be empty when notion.enabled = true","messagePattern":"notion\\.database_id must not be empty when notion\\.enabled = true","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/zeroclaw-config/src/schema.rs","lineNumber":22011,"sourceCode":"                match reqwest::Url::parse(&reg.url) {\n                    Ok(u) if matches!(u.scheme(), \"http\" | \"https\" | \"file\") => {}\n                    Ok(u) => anyhow::bail!(\n                        \"skills.extra_registries[{}].url scheme '{}' is unsupported (use http, https, or file)\",\n                        reg.name,\n                        u.scheme()\n                    ),\n                    Err(e) => anyhow::bail!(\n                        \"skills.extra_registries[{}].url is not a valid URL: {e}\",\n                        reg.name\n                    ),\n                }\n            }\n        }\n\n        // Notion\n        if self.notion.enabled {\n            if self.notion.database_id.trim().is_empty() {\n                anyhow::bail!(\"notion.database_id must not be empty when notion.enabled = true\");\n            }\n            if self.notion.poll_interval_secs == 0 {\n                validation_bail!(\n                    InvalidNumericRange,\n                    \"notion.poll_interval_secs\",\n                    \"notion.poll_interval_secs must be greater than 0\"\n                );\n            }\n            if self.notion.max_concurrent == 0 {\n                validation_bail!(\n                    InvalidNumericRange,\n                    \"notion.max_concurrent\",\n                    \"notion.max_concurrent must be greater than 0\"\n                );\n            }\n            if self.notion.status_property.trim().is_empty() {\n                validation_bail!(\n                    RequiredFieldEmpty,","sourceCodeStart":21993,"sourceCodeEnd":22029,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/crates/zeroclaw-config/src/schema.rs#L21993-L22029","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"# before\n[notion]\nenabled = true\n# database_id missing\n\n# after\n[notion]\nenabled = true\ndatabase_id = \"a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4\"\npoll_interval_secs = 300","handlingStrategy":"validation","validationCode":"fn notion_config_ok(n: &NotionConfig) -> bool {\n    !n.enabled || (!n.database_id.trim().is_empty() && n.poll_interval_secs > 0)\n}\n// call before config load/save:\nassert!(notion_config_ok(&cfg.notion), \"fix [notion] before enabling\");","typeGuard":null,"tryCatchPattern":"match cfg.validate() {\n    Ok(()) => { /* proceed */ }\n    Err(e) if e.to_string().starts_with(\"notion.database_id\") => {\n        eprintln!(\"Notion enabled without database_id — set it or disable notion\");\n        return;\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["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"],"tags":["notion","config","validation","integration","toml"],"backgroundTag":"config-validation-failed","analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}