Tencent/WeKnora · error

get block children for %s: %w

Error message

get block children for %s: %w

What it means

GetBlockChildrenFlat wraps any error from doRequest when fetching /v1/blocks/{blockID}/children. The wrapper adds the block ID for debugging; the underlying cause can be ErrInvalidCredentials (401/403), ErrResourceNotFound (404), rate limiting (429), 5xx, or network errors — all retried where applicable inside doRequest before this wrapper fires.

Source

Thrown at internal/datasource/connector/notion/client.go:249

	return &ds, nil
}

// GetBlockChildrenFlat fetches only the direct children of a block (no recursion).
// Used by discoverPages to quickly scan for child_page/child_database without
// fetching the full block tree content.
func (c *notionClient) GetBlockChildrenFlat(ctx context.Context, blockID string) ([]notionBlock, error) {
	var allBlocks []notionBlock
	var startCursor string

	for {
		path := fmt.Sprintf("/v1/blocks/%s/children", blockID)
		if startCursor != "" {
			path += "?start_cursor=" + startCursor
		}

		respBody, err := c.doRequest(ctx, http.MethodGet, path, nil)
		if err != nil {
			return nil, fmt.Errorf("get block children for %s: %w", blockID, err)
		}

		var resp paginatedResponse
		if err := json.Unmarshal(respBody, &resp); err != nil {
			return nil, fmt.Errorf("unmarshal block children response: %w", err)
		}

		var blocks []notionBlock
		if err := json.Unmarshal(resp.Results, &blocks); err != nil {
			return nil, fmt.Errorf("unmarshal blocks: %w", err)
		}

		allBlocks = append(allBlocks, blocks...)

		if !resp.HasMore || resp.NextCursor == "" {
			break
		}
		startCursor = resp.NextCursor

View on GitHub (pinned to 988cbb0330)

Solutions

  1. Read the wrapped cause: if 401/403, re-share the parent page with the integration in Notion (Settings → Connections).
  2. If 404, verify the block ID — the block may be deleted or the integration lacks access to its ancestors.
  3. In Notion, ensure all ancestor pages of the target are shared with the integration — Notion access is hierarchical.
  4. For rate-limit causes, reduce sync concurrency or retry later (see rate-limit guidance).
  5. Re-run Ping (/v1/users/me) to confirm the token is still valid.

Example fix

// before: assume block exists
blocks, err := client.GetBlockChildrenFlat(ctx, blockID)
if err != nil { return err }
// after: skip inaccessible/deleted blocks gracefully
blocks, err := client.GetBlockChildrenFlat(ctx, blockID)
if err != nil {
    if errors.Is(err, datasource.ErrResourceNotFound) {
        log.Printf("block %s gone or inaccessible, skipping", blockID)
        return nil, nil
    }
    return err
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Verify access + token before fetching children
if err := client.Ping(ctx); err != nil {
    return fmt.Errorf("invalid or revoked token: %w", err)
}
// Note: share the page containing the block with the integration in Notion UI first.

Try / catch

blocks, err := client.GetBlockChildrenFlat(ctx, blockID)
switch {
case errors.Is(err, datasource.ErrInvalidCredentials):
    // re-share page with integration / rotate token
case errors.Is(err, datasource.ErrResourceNotFound):
    // block deleted or not shared: skip gracefully
case strings.Contains(err.Error(), "rate limited"):
    // back off and retry
}

Prevention

When it happens

Trigger: doRequest fails for any of: 401/403 (token revoked or integration lacks access to the block), 404 (block deleted or wrong ID), exhausted 429 retries, exhausted 5xx retries, or transport failure — during any pagination iteration of the children loop. Also used by getBlockChildrenRecursive (same message at client.go:296).

Common situations: Integration not shared with the containing page (Notion requires explicit connection sharing → 404/403); block deleted between discovery and fetch; token rotated/revoked mid-sync; rate limits exhausted on large pages with many children pages.

Related errors


AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02). Data as JSON: /api/errors/6c0b23b239176eee. Report an issue: GitHub.