{"record":{"id":"5cfb4e443cda3a52","repo":"gastownhall/beads","slug":"retrieve-child-data-source-s-w","errorCode":null,"errorMessage":"retrieve child data source %s: %w","messagePattern":"retrieve child data source (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/notion/client.go","lineNumber":232,"sourceCode":"\tif ds, err := client.RetrieveDataSource(ctx, identifier); err == nil {\n\t\treturn &ResolvedDataSource{\n\t\t\tInputID:      identifier,\n\t\t\tDataSourceID: ds.ID,\n\t\t\tDataSource:   ds,\n\t\t\tViewURL:      strings.TrimSpace(ref),\n\t\t}, nil\n\t} else {\n\t\tdb, dbErr := client.RetrieveDatabase(ctx, identifier)\n\t\tif dbErr != nil {\n\t\t\treturn nil, fmt.Errorf(\"resolve %q as data source: %w; as database: %v\", ref, err, dbErr)\n\t\t}\n\t\tif len(db.DataSources) == 0 || strings.TrimSpace(db.DataSources[0].ID) == \"\" {\n\t\t\treturn nil, fmt.Errorf(\"database %s has no child data sources\", db.ID)\n\t\t}\n\t\tresolvedID := strings.TrimSpace(db.DataSources[0].ID)\n\t\tresolvedDS, err := client.RetrieveDataSource(ctx, resolvedID)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"retrieve child data source %s: %w\", resolvedID, err)\n\t\t}\n\t\treturn &ResolvedDataSource{\n\t\t\tInputID:      identifier,\n\t\t\tDataSourceID: resolvedID,\n\t\t\tDataSource:   resolvedDS,\n\t\t\tDatabase:     db,\n\t\t\tViewURL:      strings.TrimSpace(ref),\n\t\t}, nil\n\t}\n}\n\nfunc (c *Client) doRequest(ctx context.Context, method, path string, requestBody interface{}) ([]byte, error) {\n\tif c == nil {\n\t\treturn nil, fmt.Errorf(\"notion client is nil\")\n\t}\n\tif strings.TrimSpace(c.Token) == \"\" {\n\t\treturn nil, fmt.Errorf(\"Notion token not configured\")\n\t}","sourceCodeStart":214,"sourceCodeEnd":250,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/notion/client.go#L214-L250","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Share the underlying data source (or its parent database content) with the integration, not just the database container.","Retry with backoff if the wrapped error is 429 or 5xx (read the inner error to tell).","Verify the database still has content in Notion; re-copy the link if it was emptied or moved.","Reference the data source URL directly to skip the database->child round trip."],"exampleFix":"// before\nresolved, err := notion.ResolveDataSourceReference(ctx, client, dbID) // db visible, child DS 403\n// after\n// share the database's contents with the integration, or resolve the data source URL directly\nresolved, err := notion.ResolveDataSourceReference(ctx, client, dataSourceURLSharedWithIntegration)","handlingStrategy":"retry","validationCode":"db, err := client.RetrieveDatabase(ctx, id)\nif err != nil {\n    return fmt.Errorf(\"cannot see database %s: %w\", id, err)\n}\nif len(db.DataSources) > 0 {\n    if _, err := client.RetrieveDataSource(ctx, strings.TrimSpace(db.DataSources[0].ID)); err != nil {\n        return fmt.Errorf(\"child data source not accessible: %w\", err)\n    }\n}","typeGuard":null,"tryCatchPattern":"resolved, err := notion.ResolveDataSourceReference(ctx, client, ref)\nif err != nil && strings.Contains(err.Error(), \"retrieve child data source\") {\n    // retry with backoff for 429/5xx; otherwise fix sharing\n}","preventionTips":["Share the data source content with the integration, not only the database container","Back off and retry on 429/5xx before treating it as fatal","Re-copy links after databases are moved or emptied","Reference the data source URL directly to skip the extra lookup"],"tags":["notion","permissions","api","resource-not-found"],"backgroundTag":"notion-access-denied","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}