gastownhall/beads · error

retrieve child data source %s: %w

Error message

retrieve child data source %s: %w

What it means

After finding the first child data source ID on the database, ResolveDataSourceReference calls RetrieveDataSource on that ID to load the full data source object. Failure of that second lookup is wrapped as 'retrieve child data source %s: %w'. The database was visible, but its child data source could not be fetched.

Source

Thrown at internal/notion/client.go:232

	if ds, err := client.RetrieveDataSource(ctx, identifier); err == nil {
		return &ResolvedDataSource{
			InputID:      identifier,
			DataSourceID: ds.ID,
			DataSource:   ds,
			ViewURL:      strings.TrimSpace(ref),
		}, nil
	} else {
		db, dbErr := client.RetrieveDatabase(ctx, identifier)
		if dbErr != nil {
			return nil, fmt.Errorf("resolve %q as data source: %w; as database: %v", ref, err, dbErr)
		}
		if len(db.DataSources) == 0 || strings.TrimSpace(db.DataSources[0].ID) == "" {
			return nil, fmt.Errorf("database %s has no child data sources", db.ID)
		}
		resolvedID := strings.TrimSpace(db.DataSources[0].ID)
		resolvedDS, err := client.RetrieveDataSource(ctx, resolvedID)
		if err != nil {
			return nil, fmt.Errorf("retrieve child data source %s: %w", resolvedID, err)
		}
		return &ResolvedDataSource{
			InputID:      identifier,
			DataSourceID: resolvedID,
			DataSource:   resolvedDS,
			Database:     db,
			ViewURL:      strings.TrimSpace(ref),
		}, nil
	}
}

func (c *Client) doRequest(ctx context.Context, method, path string, requestBody interface{}) ([]byte, error) {
	if c == nil {
		return nil, fmt.Errorf("notion client is nil")
	}
	if strings.TrimSpace(c.Token) == "" {
		return nil, fmt.Errorf("Notion token not configured")
	}

View on GitHub (pinned to 71377f2769)

Solutions

  1. Share the underlying data source (or its parent database content) with the integration, not just the database container.
  2. Retry with backoff if the wrapped error is 429 or 5xx (read the inner error to tell).
  3. Verify the database still has content in Notion; re-copy the link if it was emptied or moved.
  4. Reference the data source URL directly to skip the database->child round trip.

Example fix

// before
resolved, err := notion.ResolveDataSourceReference(ctx, client, dbID) // db visible, child DS 403
// after
// share the database's contents with the integration, or resolve the data source URL directly
resolved, err := notion.ResolveDataSourceReference(ctx, client, dataSourceURLSharedWithIntegration)
Defensive patterns

Strategy: retry

Validate before calling

db, err := client.RetrieveDatabase(ctx, id)
if err != nil {
    return fmt.Errorf("cannot see database %s: %w", id, err)
}
if len(db.DataSources) > 0 {
    if _, err := client.RetrieveDataSource(ctx, strings.TrimSpace(db.DataSources[0].ID)); err != nil {
        return fmt.Errorf("child data source not accessible: %w", err)
    }
}

Try / catch

resolved, err := notion.ResolveDataSourceReference(ctx, client, ref)
if err != nil && strings.Contains(err.Error(), "retrieve child data source") {
    // retry with backoff for 429/5xx; otherwise fix sharing
}

Prevention

When it happens

Trigger: Calling ResolveDataSourceReference when RetrieveDatabase succeeds but RetrieveDataSource on the child ID fails — e.g. the database ID is visible but the data source requires separate access, a transient 429/5xx, or the data source was deleted while the database stub remained.

Common situations: Partially shared resources where the database card is shared but the data source is not; rate limiting from rapid successive resolutions; stale config pointing at a database whose contents were removed.

Related errors


AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30). Data as JSON: /api/errors/5cfb4e443cda3a52. Report an issue: GitHub.