Skip to content

fix(api): skip unsupported block-children errors instead of aborting sync#60

Open
oliver-mee wants to merge 1 commit into
openclaw:mainfrom
oliver-mee:fix/api-ai-block-sync-abort
Open

fix(api): skip unsupported block-children errors instead of aborting sync#60
oliver-mee wants to merge 1 commit into
openclaw:mainfrom
oliver-mee:fix/api-ai-block-sync-abort

Conversation

@oliver-mee

Copy link
Copy Markdown

Summary

GET /blocks/{id}/children returns a 400 validation_error when a page contains a block type the API cannot return to this integration (seen with Notion AI blocks: "Block type ai_block is not supported via the API for your bot type."). That error propagated unhandled and aborted the entire sync --source api run, the same failure shape as #37 and #39 but a different Notion block type triggering it.

This classifies that specific 400 as non-fatal: skip the unfetchable children batch, record a warning (surfaced the same way existing warnings already are, via Summary.Warnings / writeAPIWarnings on stderr), and keep syncing the rest of the workspace. It also gates the page_blocks "complete" marker and RetireSourcePageBlocksNotSyncedAt on zero warnings: without that gate, a page that synced cleanly before would have its already-synced blocks retired the next run it also happens to contain one unfetchable block. An independent review pass (Claude Opus 4.8) caught that specific regression before this PR was opened, see Model used below.

Linked issue

Fixes #59

Type of change

  • Bug fix (non-breaking)
  • New feature (non-breaking)
  • Breaking change
  • Refactor or cleanup (no behaviour change)
  • Documentation
  • CI, tooling, or config

How to test

  1. GOWORK=off go test ./..., go vet ./..., gofmt -l . all clean, including the 3 new tests (TestWalkBlocksSkipsUnsupportedBlockChildren, TestIngestPageLeavesIncompleteWhenBlockChildrenUnsupported, TestWalkBlocksDoesNotRetirePreviousBlocksOnPartialWalk).
  2. go build ./cmd/notcrawl, then run notcrawl sync --source api against a workspace with an ai_block present. I ran this against my own production workspace (7,573 pages, one page with an ai_block) and confirmed the patched binary gets past the exact page the unpatched binary aborted on, printing warning: Skipped children of block ... on page ... to stderr instead of dying.

Checklist

  • One concern only, scope limited to the summary above
  • I ran it and verified end to end: full suite, vet, gofmt, plus a real sync against a 7,573-page production workspace, not just unit tests.
    • Windows: not tested. N/A, disclosed honestly: no Windows box available. The change is pure Go with no OS-specific paths.

Model used

Claude Sonnet 5 implemented this. A separate Claude Opus 4.8 pass independently reviewed the diff and caught a real bug: the first version only gated SetSyncState(..., "complete") on the warnings, missing that RetireSourcePageBlocksNotSyncedAt needed the same gate, or a previously-clean page would lose its valid blocks the next time it also hit one unfetchable block. That fix is included here.


🤖 Generated with Claude Code (Claude Sonnet 5)
🧑‍💻 Ideated, directed and reviewed by a human, @Omee11

…sync

GET /blocks/{id}/children returns a 400 validation_error when a page
contains a block type the integration cannot receive (seen with Notion
AI blocks: "Block type ai_block is not supported via the API for your
bot type."). This aborted the entire sync --source api run, regardless
of how many other pages were left to sync.

Classify this specific 400 as non-fatal: skip the unfetchable children
batch, record a warning, and continue. The page_blocks "complete" sync
marker and RetireSourcePageBlocksNotSyncedAt are both now gated on zero
warnings, so a page that synced cleanly before does not have its
previously-synced blocks retired the next time it also contains one
unfetchable block.

Adds isUnsupportedBlockChildrenError and threads a []string warnings
return through walkBlocksAt -> walkBlocks -> ingestPage -> Sync,
reusing the existing Summary.Warnings / writeAPIWarnings stderr path
already used for the forbidden-/users and restricted-resource cases.

Covered by three new tests:
- TestWalkBlocksSkipsUnsupportedBlockChildren
- TestIngestPageLeavesIncompleteWhenBlockChildrenUnsupported
- TestWalkBlocksDoesNotRetirePreviousBlocksOnPartialWalk

Fixes openclaw#59
@clawsweeper

clawsweeper Bot commented Jul 2, 2026

Copy link
Copy Markdown

Codex review: needs maintainer review before merge. Reviewed July 2, 2026, 9:49 AM ET / 13:49 UTC.

Summary
The PR changes Notion API sync to treat unsupported block-children 400 validation errors as warnings, preserve partial page block state, and add regression tests.

Reproducibility: yes. from source: current main returns any /blocks/{id}/children API error from walkBlocksAt through ingestPage and Sync, matching the linked ai_block 400 report. I did not reproduce against a live Notion workspace in this review.

Review metrics: 2 noteworthy metrics.

  • Changed files: 2 modified. The patch is scoped to Notion API ingestion and its tests, which keeps the review surface bounded.
  • Regression tests: 3 added. The new tests cover the nonfatal unsupported-block path and the persisted block-retirement guard that prevents losing prior content.

Root-cause cluster
Relationship: fixed_by_candidate
Canonical: #59
Summary: This PR is the open candidate fix for the ai_block block-children abort described in the linked issue; the older related issues are adjacent API resilience cases with different endpoints or block types.

Members:

Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything.

Merge readiness
Overall: 🐚 platinum hermit
Proof: 🐚 platinum hermit
Patch quality: 🐚 platinum hermit
Result: ready for maintainer review.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • none.

Risk before merge

  • [P1] I did not run a live Notion workspace in this read-only review; the positive real behavior proof comes from the PR body's production-workspace run and redacted warning output.
  • [P1] The Go test, vet, build, and gofmt results are contributor-reported; I did not run them because this review kept the checkout read-only.

Maintainer options:

  1. Decide the mitigation before merge
    Land this PR if maintainers accept the targeted warning predicate and normal Go checks pass; keep the change scoped to the API ingestion bug tracked at API sync aborts on ai_block children returning 400 validation_error #59.
  2. Pause or close
    Do not merge this PR until maintainers decide whether the risk is worth taking.

Next step before merge

  • No automated repair job is needed because this PR already contains the focused fix and review found no concrete patch blocker.

Security
Cleared: The diff only changes Go API error handling and tests; it does not add dependencies, CI execution, secrets handling, or broader supply-chain surface.

Review details

Best possible solution:

Land this PR if maintainers accept the targeted warning predicate and normal Go checks pass; keep the change scoped to the API ingestion bug tracked at #59.

Do we have a high-confidence way to reproduce the issue?

Yes from source: current main returns any /blocks/{id}/children API error from walkBlocksAt through ingestPage and Sync, matching the linked ai_block 400 report. I did not reproduce against a live Notion workspace in this review.

Is this the best way to solve the issue?

Yes; the PR uses a narrow validation_error predicate, preserves warning visibility through the existing Summary.Warnings path, and avoids marking or retiring page blocks after a partial walk.

AGENTS.md: not found in the target repository.

Codex review notes: model internal, reasoning high; reviewed against 7754b9d416df.

Label changes

Label changes:

  • add P2: This fixes a bounded but real API sync abort where one unsupported Notion block can stop the workspace sync.
  • add proof: sufficient: Contributor real behavior proof is sufficient. The PR body reports an after-fix real notcrawl sync --source api run against a 7,573-page workspace with an ai_block and includes the observed warning behavior instead of the prior abort.
  • add rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🐚 platinum hermit and patch quality is 🐚 platinum hermit.
  • add status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (live_output): The PR body reports an after-fix real notcrawl sync --source api run against a 7,573-page workspace with an ai_block and includes the observed warning behavior instead of the prior abort.

Label justifications:

  • P2: This fixes a bounded but real API sync abort where one unsupported Notion block can stop the workspace sync.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🐚 platinum hermit and patch quality is 🐚 platinum hermit.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (live_output): The PR body reports an after-fix real notcrawl sync --source api run against a 7,573-page workspace with an ai_block and includes the observed warning behavior instead of the prior abort.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR body reports an after-fix real notcrawl sync --source api run against a 7,573-page workspace with an ai_block and includes the observed warning behavior instead of the prior abort.
Evidence reviewed

What I checked:

  • No target AGENTS.md found: The repository file search found no AGENTS.md and no matching maintainer notes, so no target-specific policy changed this review.
  • Current main still aborts on block-children API errors: On current main, Sync returns ingestPage errors, ingestPage returns walkBlocks errors, and walkBlocksAt returns any /blocks/{id}/children API error directly instead of warning and continuing. (internal/notionapi/api.go:398, 7754b9d416df)
  • Latest release has the same fatal path: v0.5.1 points at 5637c35 and its walkBlocksAt implementation still returns the block-children error at the request site. (internal/notionapi/api.go:398, 5637c35da08a)
  • PR diff implements targeted warning propagation: The PR threads warnings through Sync, ingestPage, walkBlocks, and walkBlocksAt, recognizes a 400 validation_error containing 'not supported via the API', and skips retirement/completion when warnings were produced. (internal/notionapi/api.go:419, 839ba312a612)
  • Regression coverage added: The PR adds tests for skipping unsupported block children, leaving page_blocks incomplete on a skipped batch, and preserving previously synced blocks during a partial walk. (internal/notionapi/api_test.go:443, 839ba312a612)
  • Linked issue owns the reported bug: The PR has a closing reference to API sync aborts on ai_block children returning 400 validation_error #59, whose report says v0.5.1 and main at 7754b9d abort on a Notion ai_block 400 validation_error. (839ba312a612)

Likely related people:

  • Peter Steinberger: git blame attributes the current Notion API Sync and walkBlocks implementation in this checkout to the v0.5.1 release commit. (role: current implementation introducer; confidence: medium; commits: 5637c35da08a; files: internal/notionapi/api.go, internal/notionapi/api_test.go)
  • davelutztx: Recent prior commits in the same Notion API area handled inaccessible comments and block display order, which are adjacent to this sync-resilience path. (role: adjacent API resilience contributor; confidence: medium; commits: 47e96fd4c0b0, 25be299fab67; files: internal/notionapi/api.go, internal/notionapi/api_test.go)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@clawsweeper clawsweeper Bot added proof: sufficient Contributor real behavior proof is sufficient. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. P2 Normal priority bug or improvement with limited blast radius. labels Jul 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

fix P2 Normal priority bug or improvement with limited blast radius. proof: sufficient Contributor real behavior proof is sufficient. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

API sync aborts on ai_block children returning 400 validation_error

2 participants