zeroclaw-labs/zeroclaw · error · anyhow::Error
Notion create_page failed ({status}): {truncated}
Error message
Notion create_page failed ({status}): {truncated} What it means
The Notion tool's create_page action sent POST https://api.notion.com/v1/pages and Notion rejected it with a non-2xx status; the message includes the status and truncated response body explaining why the page could not be created.
Source
Thrown at crates/zeroclaw-tools/src/notion_tool.rs:126
let url = format!("{NOTION_API_BASE}/pages");
let mut body = json!({ "properties": properties });
if let Some(db_id) = database_id {
body["parent"] = json!({ "database_id": db_id });
}
let resp = self
.http
.post(&url)
.headers(self.headers()?)
.json(&body)
.timeout(std::time::Duration::from_secs(NOTION_REQUEST_TIMEOUT_SECS))
.send()
.await?;
let status = resp.status();
if !status.is_success() {
let text = resp.text().await.unwrap_or_default();
let truncated =
crate::util_helpers::truncate_with_ellipsis(&text, MAX_ERROR_BODY_CHARS);
anyhow::bail!("Notion create_page failed ({status}): {truncated}");
}
resp.json().await.map_err(Into::into)
}
/// Update an existing Notion page's properties.
async fn update_page(
&self,
page_id: &str,
properties: &serde_json::Value,
) -> anyhow::Result<serde_json::Value> {
let url = format!("{NOTION_API_BASE}/pages/{page_id}");
let body = json!({ "properties": properties });
let resp = self
.http
.patch(&url)
.headers(self.headers()?)
.json(&body)
.timeout(std::time::Duration::from_secs(NOTION_REQUEST_TIMEOUT_SECS))View on GitHub (pinned to 88bb9c8533)
Solutions
- Inspect the status and body excerpt: 400 validation_error usually names the offending property
- Read the parent database first and build the properties payload from its actual property names and types
- For 404, share the parent database/page with the integration before creating under it
- Confirm the title property is included and typed as title/rich_text as the schema requires
- For auth failures, rotate and reconfigure the integration token
Example fix
// before (property 'Priority' is a number in the database)
{"action":"create_page","parent":{"database_id":"<id>"},"properties":{"Priority":{"rich_text":[{"text":{"content":"high"}}]}}}
// after
{"action":"create_page","parent":{"database_id":"<id>"},"properties":{"Priority":{"number":1}}} Defensive patterns
Strategy: validation
Validate before calling
// Build properties from the live schema: read the database, map each property
type, then emit
fn coerce_value(prop_type: &str, raw: &str) -> serde_json::Value {
match prop_type {
"number" => json!({"number": raw.parse::<f64>().unwrap_or(0.0) }),
"select" => json!({"select": {"name": raw } }),
_ => json!({"rich_text": [{"text": {"content": raw }}]}),
}
} Try / catch
Err(e) if e.to_string().contains("create_page failed (400)") => {
// re-read parent schema, rebuild payload once, then fail loudly if still 400
} Prevention
- Never hardcode property payloads; generate them from the database schema at run time
- Prefer creating pages under parents the integration already reads successfully
- Add a canary create+archive call in deployment checks to catch schema drift early
When it happens
Trigger: Parent database or page not shared with the integration (404); properties payload that does not match the parent database's schema, e.g. sending a title value for a property defined as a number (400 validation_error); missing required title property; invalid parent object; bad token (401/403).
Common situations: Automations that create rows from templates break when the database schema changes (a property renamed or retyped) while the payload was hardcoded. Also: creating a page under a parent page that the integration cannot see, and copy-pasted payloads from a different database.
Related errors
- Notion read_page failed ({status}): {truncated}
- Notion update_page failed ({status}): {truncated}
- Notion query_database failed ({status}): {truncated}
- Notion search failed ({status}): {truncated}
- Failed to initiate call: {}
AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23).
Data as JSON: /api/errors/08934f2b0b5b8b58.
Report an issue: GitHub.