Skip to content

Tolerate a stale Notion database ID and title property - #12

Draft
dplakon wants to merge 1 commit into
mainfrom
fix/notion-database-resolution
Draft

Tolerate a stale Notion database ID and title property#12
dplakon wants to merge 1 commit into
mainfrom
fix/notion-database-resolution

Conversation

@dplakon

@dplakon dplakon commented Aug 4, 2026

Copy link
Copy Markdown

Problem

Found while running the daily pipeline: find_company_page() fails outright in the deployed grainiac environment.

  • The provisioned GRAINIAC_NOTION_DATABASE_ID (3a043263616d803d98de000c5b916204) returns Notion 404 on GET /databases/{id}, POST /databases/{id}/query, GET /pages/{id} and GET /blocks/{id} — that database is not shared with the integration.
  • The database that is shared is "Account Management" (3a043263-616d-80bd-a6da-f099fa90796a), and its title property is Account name — not Company (the code default) and not Name (the value configured in the environment).

Both failure modes are worse than a crash. A wrong title property makes the title-equals query return zero rows, and a "no page found" result sends the meeting processor down the create path — writing duplicate company pages alongside the real ones. The name inferred from email domains (Chargepoint, Imc) also never title-matches the real page names (ChargePoint, IMC), so even a correctly configured database would produce duplicates.

Both meeting-processor agents had to independently hand-roll a /search-based workaround to get their work done.

Change

  • resolve_database() resolves (database_id, title_property) once and caches it. It uses the configured ID when the integration can actually read it, and otherwise discovers the shared database via POST /search, disambiguated by the new optional GRAINIAC_NOTION_DATABASE_NAME.
  • The title property is now read from the database schema. A configured GRAINIAC_NOTION_TITLE_PROPERTY is honored only if it actually exists on the database; otherwise the real title property is used and a warning is logged.
  • find_company_page() tries the exact title query, then falls back to a case-insensitive scan of the database (paginated), so Chargepoint resolves to the existing ChargePoint page.
  • If the database is unreachable entirely, find_company_page() falls back to a POST /search title lookup. Page and block writes need no database access, so the rest of the processor works unchanged.
  • Every fallback logs to stderr, so the underlying misconfiguration stays visible instead of being silently papered over.

_database_id() / _title_property() keep their signatures, and explicit database_id / title_property arguments still win, so existing callers are unaffected.

Verification

Against the live workspace, with the stale ID and wrong title property still set in the environment:

Warning: configured GRAINIAC_NOTION_DATABASE_ID (3a043263616d803d98de000c5b916204) is not readable by this integration (Notion API 404 ...); discovering the shared database instead.
Using Notion database 'Account Management' (3a043263-616d-80bd-a6da-f099fa90796a) discovered via /search.
Warning: GRAINIAC_NOTION_TITLE_PROPERTY='Name' is not a property of this database; using the actual title property 'Account name'.
resolved db: 3a043263-616d-80bd-a6da-f099fa90796a
resolved title prop: Account name
find_company_page('ChargePoint') -> ('3a543263-616d-81ea-87a9-cbb7ecdca534', 'ChargePoint')
find_company_page('Chargepoint') -> ('3a543263-616d-81ea-87a9-cbb7ecdca534', 'ChargePoint')
find_company_page('IMC')         -> ('3a443263-616d-8180-919f-fbbea10ed1b5', 'IMC')
find_company_page('Imc')         -> ('3a443263-616d-8180-919f-fbbea10ed1b5', 'IMC')
find_company_page('NoSuchCompanyXYZ') -> None

The two resolved page IDs match the pages the meeting-processor agents updated by hand.

Note for maintainers

This makes the code resilient, but the environment config is still wrong and should be corrected independently: GRAINIAC_NOTION_DATABASE_ID should point at 3a043263-616d-80bd-a6da-f099fa90796a (or that database should be shared with the integration), and GRAINIAC_NOTION_TITLE_PROPERTY can simply be unset.

Conversation: https://app.warp.dev/conversation/f92e17e1-1b36-44b0-bfd9-41425daff5c8
Run: https://oz.warp.dev/runs/019fcb24-a1bf-7109-9854-cab556a23ecc

This PR was generated with Oz.

`find_company_page()` failed outright in the deployed environment: the
configured GRAINIAC_NOTION_DATABASE_ID answers Notion 404 because that
database is not shared with the integration, and the configured
GRAINIAC_NOTION_TITLE_PROPERTY was not a property of the database that
is shared. Either misconfiguration silently breaks the create-vs-update
decision, and the "no page found" path would create duplicate company
pages next to the real ones.

- Resolve the database once via `resolve_database()`: use the configured
  ID when the integration can read it, otherwise discover the shared
  database with /search (disambiguated by GRAINIAC_NOTION_DATABASE_NAME).
- Read the title property from the database schema instead of trusting
  config, warning when the configured name does not exist.
- Match company names case-insensitively after the exact-title query, so
  a name inferred from an email domain ("Chargepoint") finds the
  existing page ("ChargePoint") instead of creating a duplicate.
- Fall back to a /search title lookup if the database is unreachable
  entirely, since page and block writes do not need database access.

Every fallback logs to stderr so the underlying misconfiguration stays
visible rather than being papered over.

Co-Authored-By: Oz <oz-agent@warp.dev>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants