{"record":{"id":"82cf26f1027e7806","repo":"thedotmack/claude-mem","slug":"onboarding-explainer-not-available","errorCode":null,"errorMessage":"Onboarding explainer not available","messagePattern":"Onboarding explainer not available","errorType":"http","errorClass":null,"httpStatus":404,"severity":"info","filePath":"src/services/worker/http/routes/SearchRoutes.ts","lineNumber":442,"sourceCode":"    }\n\n    res.json({ context: lines.join('\\n'), count: observations.length });\n  });\n\n  private queryWithPlatformSource(req: Request): Record<string, any> {\n    const platformSource = this.getOptionalPlatformSourceFromRequest(req);\n    if (!platformSource) {\n      return req.query as Record<string, any>;\n    }\n    return {\n      ...(req.query as Record<string, any>),\n      platformSource,\n    };\n  }\n\n  private handleOnboardingExplainer = this.wrapHandler((_req: Request, res: Response): void => {\n    if (cachedOnboardingExplainer === null) {\n      res.status(404).json({ error: 'Onboarding explainer not available' });\n      return;\n    }\n    res.setHeader('Content-Type', 'text/markdown; charset=utf-8');\n    res.send(cachedOnboardingExplainer);\n  });\n\n  private handleGetTimelineByQuery = this.wrapHandler(async (req: Request, res: Response): Promise<void> => {\n    const result = await this.searchManager.getTimelineByQuery(this.queryWithPlatformSource(req));\n    res.json(result);\n  });\n}\n","sourceCodeStart":424,"sourceCodeEnd":454,"githubUrl":"https://github.com/thedotmack/claude-mem/blob/8bc631a71a487424b866756e43a6efa4574cc66b/src/services/worker/http/routes/SearchRoutes.ts#L424-L454","documentation":"HTTP 404 from the onboarding-explainer endpoint. The markdown asset is read once at module load (SearchRoutes.ts:23) from ../skills/how-it-works/onboarding-explainer.md relative to the compiled file; if that read fails the cache is null and every request to the endpoint 404s for the process lifetime. It is a packaging/asset problem, not a runtime failure.","triggerScenarios":"GET the onboarding explainer route when the markdown file was not shipped in the build output — typically running from a source checkout or a package layout where the skills/ directory is excluded from the bundle.","commonSituations":"Custom builds that tree-shake non-code assets; running the worker from a repo clone without the full build-and-sync step; a plugin/UI that unconditionally renders the explainer on first run and shows an error tile instead of hiding itself.","solutions":["Treat 404 as 'feature absent' and hide/disable the explainer UI section","If you package the worker yourself, ensure skills/how-it-works/onboarding-explainer.md is copied next to the compiled routes","Restarting alone will not help — the file must exist at boot; check the boot log line 'Onboarding explainer not present at boot'"],"exampleFix":"// before\nconst md = await (await fetch(`${base}/api/onboarding/explainer`)).text();\nshow(md); // renders raw 404 JSON\n\n// after\nconst r = await fetch(`${base}/api/onboarding/explainer`);\nif (r.ok) show(await r.text());\nelse hideExplainerSection(); // 404 means asset not bundled","handlingStrategy":"fallback","validationCode":"const r = await fetch(`${base}/api/onboarding/explainer`);\nconst explainer = r.ok ? await r.text() : null; // null => feature not shipped","typeGuard":"function explainerAvailable(res: Response): boolean {\n  return res.ok && (res.headers.get('content-type') ?? '').includes('text/markdown');\n}","tryCatchPattern":null,"preventionTips":["Design UI to hide the explainer section on 404 rather than show an error","When packaging the worker, include skills/how-it-works/onboarding-explainer.md in build output","Smoke-test the endpoint after custom builds since the asset is cached at boot only"],"tags":["http-404","static-asset","onboarding","packaging"],"backgroundTag":"bundled-asset-missing","analyzedSha":"8bc631a71a487424b866756e43a6efa4574cc66b","analyzedAt":"2026-08-20T23:58:13.836Z","contentChangedAt":"2026-08-20T23:58:13.836Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}