{"record":{"id":"b0ba2aa1a7fd8665","repo":"santifer/career-ops","slug":"no-applications-database-found-under-the-career","errorCode":null,"errorMessage":"No \"Applications\" database found under the Career Ops page — create it and share the integration with it.","messagePattern":"No \"Applications\" database found under the Career Ops page — create it and share the integration with it\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"plugins/notion/index.mjs","lineNumber":37,"sourceCode":"// internal integration. Enable in config/plugins.yml; keys in .env.\n//\n//   node plugins.mjs run notion export            # mirror tracker → Notion\n//   node plugins.mjs run notion search \"platform\" # read matching records → pipeline\n\nimport { createNotionClient, rich, canonicalStatus } from './_notion.mjs';\n\nfunction clientFromCtx(ctx) {\n  return createNotionClient({\n    token: ctx?.env?.NOTION_ACCESS_TOKEN,\n    parent: ctx?.env?.NOTION_PARENT_PAGE_ID,\n    fetch: ctx?.fetch, // route through the engine's allowedHosts/redirect guard\n  });\n}\n\nasync function applicationsDb(client) {\n  const dbs = await client.resolveDBs();\n  const apps = dbs['Applications'];\n  if (!apps) throw new Error('No \"Applications\" database found under the Career Ops page — create it and share the integration with it.');\n  return apps;\n}\n\n/**\n * Parse a tracker score cell into a numeric value for the Notion DB Score property.\n *\n * Scores in applications.md may be formatted like `4.2/5`, `**4.2/5**`, `4.25`, etc.\n * Strips formatting and extracts the first numeric value so slash-formatted\n * scores (e.g. 4.2/5) are not mangled into 4.25 (#1414).\n *\n * @param {unknown} s - Raw score value from tracker row.\n * @returns {number} Parsed score, or NaN if no valid number is present.\n */\nexport function parseScore(s) {\n  const m = String(s ?? '').replace(/\\*\\*/g, '').match(/([\\d.]+)/);\n  return m ? parseFloat(m[1]) : NaN;\n}\n","sourceCodeStart":19,"sourceCodeEnd":55,"githubUrl":"https://github.com/santifer/career-ops/blob/aac998c7ed7248ea853b720ceeb1fdbeb322fc5d/plugins/notion/index.mjs#L19-L55","documentation":"The Notion plugin for career-ops looks up a database literally named 'Applications' among the databases shared with the integration and nested under the Career Ops page (via client.resolveDBs()). This error is thrown when the integration can authenticate and list databases but none matches that name. It means the Notion workspace setup is incomplete, not a code or auth failure.","triggerScenarios":"Calling applicationsDb(client) (used by every Notion sync operation) when the 'Applications' database does not exist under the Career Ops page, or exists but was not shared with the integration, or is named differently (e.g. 'Applications tracker', extra whitespace, different capitalization).","commonSituations":"Fresh install where the user created the Career Ops page but not the database; the database lives on another page or in another team space not shared with the integration; the database was renamed or recreated after initial setup; the integration received access to the page but the database was moved out from under it; a typo in the database title when creating it manually.","solutions":["Create a database titled exactly 'Applications' (case-sensitive) as a child of the Career Ops page in Notion","Share the database (and its parent page) with the integration: in Notion open the page -> ... menu -> Connections -> add your integration","Verify the database title has no leading/trailing spaces or alternate naming, then re-run the sync","If the database lives elsewhere, move it under the Career Ops page or share it directly with the integration so resolveDBs() can enumerate it"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Before any Notion sync, confirm the DB is reachable\nconst dbs = await client.resolveDBs();\nif (!dbs['Applications']) {\n  throw new Error('Notion: create an \"Applications\" database under the Career Ops page and share the integration with it.');\n}","typeGuard":"function hasApplicationsDb(dbs) {\n  return dbs != null && typeof dbs === 'object' && 'Applications' in dbs;\n}","tryCatchPattern":"try {\n  await notionSyncTracker();\n} catch (e) {\n  if (e.message.includes('No \"Applications\" database found')) {\n    console.error('Setup incomplete: create the \"Applications\" DB under the Career Ops page and connect the integration (Notion -> page -> Connections).');\n  } else throw e;\n}","preventionTips":["Create the 'Applications' database (exact title, no stray spaces) as a child of the Career Ops page during initial setup","Always share both the page and the database with the integration via Notion's Connections menu","Run doctor/setup checks that call resolveDBs() at startup and fail fast with a setup hint","Avoid renaming the database; if you must, update the plugin's expected name in the same change"],"tags":["notion","configuration","integration","database"],"backgroundTag":"resource-not-found","analyzedSha":"aac998c7ed7248ea853b720ceeb1fdbeb322fc5d","analyzedAt":"2026-09-16T06:35:29.214Z","contentChangedAt":"2026-09-16T06:35:29.214Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}