{"record":{"id":"f846091853bb5e15","repo":"tinyhumansai/openhuman","slug":"provider-chain-source-marker-not-found-in-app-tsx","errorCode":null,"errorMessage":"provider-chain source marker not found in App.tsx; expected `@generated-source:provider-chain` … `@end-source:provider-chain`","messagePattern":"provider-chain source marker not found in App\\.tsx; expected `@generated-source:provider-chain` … `@end-source:provider-chain`","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/generate-architecture-docs.mjs","lineNumber":52,"sourceCode":"export const FRONTEND_DOC = resolve(REPO_ROOT, 'gitbooks/developing/architecture/frontend.md');\n\n/** Stable tokens used to locate the generated block in the doc. */\nconst BLOCK_BEGIN_TOKEN = 'BEGIN GENERATED: provider-chain';\nconst BLOCK_END_TOKEN = 'END GENERATED: provider-chain';\n\n/**\n * Parse the ordered provider chain out of the `@generated-source:provider-chain`\n * marker block in App.tsx source text.\n *\n * @param {string} appSource - contents of App.tsx\n * @returns {{ order: number, name: string, role: string }[]}\n * @throws if the marker block is missing, empty, or rows are malformed / non-contiguous\n */\nexport function parseProviderChain(appSource) {\n  const begin = appSource.indexOf('@generated-source:provider-chain');\n  const end = appSource.indexOf('@end-source:provider-chain');\n  if (begin === -1 || end === -1 || end < begin) {\n    throw new Error(\n      'provider-chain source marker not found in App.tsx; expected ' +\n        '`@generated-source:provider-chain` … `@end-source:provider-chain`'\n    );\n  }\n  const region = appSource.slice(begin, end);\n  const rowRe = /^\\s*\\*?\\s*(\\d+)\\.\\s+(.+?)\\s+—\\s+(.+?)\\s*$/;\n  const providers = [];\n  for (const line of region.split('\\n')) {\n    const m = rowRe.exec(line);\n    if (!m) continue;\n    providers.push({ order: Number(m[1]), name: m[2].trim(), role: m[3].trim() });\n  }\n  if (providers.length === 0) {\n    throw new Error('provider-chain source marker contained no `N. Component — role` rows');\n  }\n  // Guard against drift in the marker itself: orders must be 1..N, in order,\n  // names non-empty, and roles free of the `|` that would break the table.\n  providers.forEach((p, i) => {","sourceCodeStart":34,"sourceCodeEnd":70,"githubUrl":"https://github.com/tinyhumansai/openhuman/blob/a221052e0df5b1f7598fceba7329fd1af95d6699/scripts/generate-architecture-docs.mjs#L34-L70","documentation":"Thrown by parseProviderChain() in the docs generator (issue #3892 slice) when app/src/App.tsx no longer contains a valid source-of-truth marker block. The generator derives the documented frontend provider chain from the comment between the literal markers `@generated-source:provider-chain` and `@end-source:provider-chain`; if either marker string is absent (indexOf === -1) or the end marker appears before the begin marker, it refuses to run rather than emit an empty table.","triggerScenarios":"Running `node scripts/generate-architecture-docs.mjs` (or `pnpm docs:generate` / `pnpm docs:check`) after the marker comment block in App.tsx was deleted, reworded (e.g. `@generated-source:providers`), or the two marker lines were reordered so `@end-source:provider-chain` precedes `@generated-source:provider-chain`. Also hit if APP_TSX resolves to a file that is not the real app/src/App.tsx.","commonSituations":"Refactoring the provider chain in App.tsx and rewriting/stripping the surrounding block comment; IDE 'clean up comments' or a lint rule removing what looks like a dead comment; hand-merging a conflict that drops the marker lines.","solutions":["Recover the marker block with `git log -p -- app/src/App.tsx` and restore it verbatim between `@generated-source:provider-chain` and `@end-source:provider-chain`, keeping the `N. Component — role` rows","Check the marker spellings character-by-character — both are literal indexOf matches; a renamed or misspelled marker is invisible to the parser","Confirm the end marker sits BELOW the begin marker inside the same comment block","Re-run `pnpm docs:generate` then `pnpm docs:check` to confirm the drift gate passes"],"exampleFix":"// before — App.tsx comment block edited, markers gone:\n/*\n * Provider chain: Sentry -> Redux -> PersistGate ...\n */\n\n// after — markers restored as the parseable source of truth:\n/*\n * @generated-source:provider-chain\n * 1. Sentry.ErrorBoundary — global crash boundary\n * 2. Redux Provider — app-wide store\n * ...\n * @end-source:provider-chain\n */","handlingStrategy":"validation","validationCode":"// Preflight before pnpm docs:generate / docs:check\nimport { readFileSync } from 'node:fs';\nconst src = readFileSync('app/src/App.tsx', 'utf8');\nconst begin = src.indexOf('@generated-source:provider-chain');\nconst end = src.indexOf('@end-source:provider-chain');\nif (begin === -1 || end === -1 || end < begin) {\n  console.error(`App.tsx marker check failed: begin=${begin} end=${end} — restore the marker block first`);\n  process.exit(1);\n}","typeGuard":null,"tryCatchPattern":"try {\n  const { updated, current } = computeFrontendDoc();\n} catch (err) {\n  if (err.message.includes('source marker not found')) {\n    console.error('App.tsx lost its @generated-source:provider-chain block — recover it with `git log -p -- app/src/App.tsx`');\n    process.exitCode = 1;\n  } else throw err;\n}","preventionTips":["Treat the marker block in App.tsx as load-bearing generated-source metadata, not a disposable comment — mention it in PR review when App.tsx diff touches comments","Keep `pnpm docs:check` (Docs Drift lane) green so marker damage surfaces in CI, not at the next docs regen","When relocating the provider chain, move the marker block with it and re-run docs:generate in the same PR"],"tags":["docs","codegen","drift","developer-tooling"],"backgroundTag":null,"analyzedSha":"a221052e0df5b1f7598fceba7329fd1af95d6699","analyzedAt":"2026-08-16T12:47:06.542Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}