{"record":{"id":"144cd1baf76d562a","repo":"paperclipai/paperclip","slug":"adapter-ui-loader-failed-to-load-ui-parser-for","errorCode":null,"errorMessage":"[adapter-ui-loader] Failed to load UI parser for \"${adapterType}\":","messagePattern":"\\[adapter-ui-loader\\] Failed to load UI parser for \"(.+?)\":","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"ui/src/adapters/dynamic-loader.ts","lineNumber":250,"sourceCode":"      const response = await fetch(`/api/adapters/${encodeURIComponent(adapterType)}/ui-parser.js`);\n      if (!response.ok) {\n        failedLoads.add(adapterType);\n        return null;\n      }\n\n      const source = await response.text();\n\n      // Initialise the sandboxed worker with the parser source.\n      const sandbox = await initSandboxedWorker(source);\n      sandboxedParsers.set(adapterType, sandbox);\n\n      const parserModule = buildParserModule(sandbox);\n      dynamicParserCache.set(adapterType, parserModule);\n\n      console.info(`[adapter-ui-loader] Loaded sandboxed UI parser for \"${adapterType}\"`);\n      return parserModule;\n    } catch (err) {\n      console.warn(`[adapter-ui-loader] Failed to load UI parser for \"${adapterType}\":`, err);\n      failedLoads.add(adapterType);\n      return null;\n    } finally {\n      loadPromises.delete(adapterType);\n    }\n  })();\n\n  loadPromises.set(adapterType, loadPromise);\n  return loadPromise;\n}\n\n/**\n * Invalidate a cached dynamic parser, removing it from both the parser cache\n * and the failed-loads set so that the next load attempt will try again.\n * Also terminates the sandboxed worker if one exists.\n */\nexport function invalidateDynamicParser(adapterType: string): boolean {\n  const wasCached = dynamicParserCache.has(adapterType);","sourceCodeStart":232,"sourceCodeEnd":268,"githubUrl":"https://github.com/paperclipai/paperclip/blob/120ae5428fa29bee300bcf806491cd4d965fbb7c/ui/src/adapters/dynamic-loader.ts#L232-L268","documentation":"A browser console warning from the board UI's dynamic adapter parser loader. The UI fetched /api/adapters/:type/ui-parser.js successfully (a 404 would take a different silent path), but initializing the sandboxed Web Worker failed: the worker reported an error evaluating the parser source (syntax error, throw at top level), raised an onerror, or did not signal readiness within the 5-second init timeout. The loader then adds the adapter type to failedLoads, so it will not retry until invalidateDynamicParser is called, and transcripts for that adapter render raw lines instead of parsed entries.","triggerScenarios":"An external adapter's ui-parser.js contains a syntax error or throws during evaluation; the browser blocks/terminates worker scripts (strict CSP without worker-src, security extensions); a slow device or heavy main thread pushes worker init past the 5000 ms timeout; a partially uploaded/corrupted parser artifact on the server.","commonSituations":"Publishing a plugin with an untranspiled or hand-edited parser bundle; Content-Security-Policy changes that forgot worker-src;开发和生产环境差异 where the artifact was built with newer syntax than the user's browser supports.","solutions":["Open the warned Error object in the console — 'Worker error: <message>' names the parser's syntax/runtime failure; 'Parser worker init timed out' indicates the 5s budget","Re-validate the adapter's ui-parser.js artifact (syntax-check it with node --check) and re-upload the plugin","Call invalidateDynamicParser(adapterType) or reload the board to clear the failedLoads cache and retry","Ensure CSP allows worker scripts (worker-src blob: or the applicable source) if workers never start"],"exampleFix":"// before: one failed init permanently disables parsing for the session\nconst parser = await loadDynamicParser(adapterType);\n\n// after: retry once after cache invalidation, then fall back to raw lines\nlet parser = await loadDynamicParser(adapterType);\nif (!parser) {\n  invalidateDynamicParser(adapterType); // clears failedLoads + terminates stale worker\n  parser = await loadDynamicParser(adapterType);\n}\nregisterParser(adapterType, parser ?? { parseStdoutLine: () => [] }); // raw-line fallback","handlingStrategy":"fallback","validationCode":"async function tryLoadParser(adapterType: string) {\n  let parser = await loadDynamicParser(adapterType);\n  if (!parser) {\n    invalidateDynamicParser(adapterType); // clear failedLoads so one retry is possible\n    parser = await loadDynamicParser(adapterType);\n  }\n  // Explicit raw-line fallback keeps transcripts usable either way\n  return parser ?? { parseStdoutLine: () => [] };\n}","typeGuard":null,"tryCatchPattern":"try {\n  parser = await loadDynamicParser(adapterType);\n} catch {\n  console.warn(`Dynamic parser load threw for ${adapterType}; falling back to raw lines`);\n  parser = null;\n}\nrenderTranscript(parser ?? { parseStdoutLine: () => [] });","preventionTips":["Syntax-check adapter parser bundles (node --check) before publishing plugins","Keep CSP permissive for worker scripts (worker-src) so sandboxed parsers can start","Remember failedLoads caches failures for the session — call invalidateDynamicParser or reload to retry after fixing the artifact","Design transcript rendering to degrade to raw lines whenever the parser module is null"],"tags":["ui","web-worker","adapters","parser","sandbox","console-warning"],"backgroundTag":"web-worker-init-failure","analyzedSha":"120ae5428fa29bee300bcf806491cd4d965fbb7c","analyzedAt":"2026-08-18T22:49:45.177Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}