{"record":{"id":"895fcf4c89c99e39","repo":"nexu-io/open-design","slug":"local-daemon-refresh-sources-require-source-type-d","errorCode":null,"errorMessage":"local daemon refresh sources require source.type daemon_tool or local_file","messagePattern":"local daemon refresh sources require source\\.type daemon_tool or local_file","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/daemon/src/live-artifacts/refresh.ts","lineNumber":723,"sourceCode":"\nexport async function executeLocalDaemonRefreshSource(options: ExecuteLocalDaemonRefreshSourceOptions): Promise<BoundedJsonObject> {\n  if (options.source.type === 'local_file') {\n    const toolName = options.source.toolName ?? 'project_files.read_json';\n    if (toolName !== 'project_files.read_json') {\n      throw new Error(`unsupported local_file refresh tool: ${toolName}`);\n    }\n    return executeProjectFilesReadJson({\n      ...options,\n      source: {\n        ...options.source,\n        type: 'daemon_tool',\n        toolName,\n      },\n    });\n  }\n\n  if (options.source.type !== 'daemon_tool') {\n    throw new Error('local daemon refresh sources require source.type daemon_tool or local_file');\n  }\n  if (!isLocalDaemonRefreshToolName(options.source.toolName)) {\n    throw new Error(`unsupported local daemon refresh tool: ${options.source.toolName ?? '<missing>'}`);\n  }\n\n  switch (options.source.toolName) {\n    case 'project_files.search':\n      return executeProjectFilesSearch(options);\n    case 'project_files.read_json':\n      return executeProjectFilesReadJson(options);\n    case 'git.summary':\n      return executeGitSummary(options);\n    case 'public_github_repository_metric':\n      return executePublicGithubRepositoryMetric(options);\n  }\n}\n","sourceCodeStart":705,"sourceCodeEnd":740,"githubUrl":"https://github.com/nexu-io/open-design/blob/5be4028344c2eb4c667c5a97bda8f750c5597ef7/apps/daemon/src/live-artifacts/refresh.ts#L705-L740","documentation":"Thrown by executeLocalDaemonRefreshSource when source.type is neither 'local_file' nor 'daemon_tool'. These are the only two source types the local daemon refresh dispatcher accepts; anything else (including undefined, typos like 'daemon-tools' or 'local_files', or unsupported future types) is rejected at the boundary.","triggerScenarios":"source.type is 'http', 'webhook', 'cron', undefined, 'remote', or a typo like 'daemon-tool' or 'localfile'.","commonSituations":"Schema drift between model-authored JSON and the daemon contract; stale documentation or example payload used a retired type name; type field accidentally omitted from the source object.","solutions":["Set source.type to 'daemon_tool' (preferred for general use) or 'local_file' (read_json alias).","Confirm there is no third supported type — do not invent one.","If extending the dispatcher to a new type, update isLocalDaemonRefreshToolName and the switch in executeLocalDaemonRefreshSource together."],"exampleFix":"// before\nsource: { type: 'http', toolName: '...', input: {...} }\n// after\nsource: { type: 'daemon_tool', toolName: '...', input: {...} }","handlingStrategy":"validation","validationCode":"const REFRESH_TYPES = new Set(['local_file', 'daemon_tool']);\nfunction assertRefreshType(t: unknown): asserts t is 'local_file' | 'daemon_tool' {\n  if (!REFRESH_TYPES.has(t as string)) throw new Error('unsupported refresh source.type');\n}","typeGuard":"function isRefreshSourceType(v: unknown): v is 'local_file' | 'daemon_tool' {\n  return v === 'local_file' || v === 'daemon_tool';\n}","tryCatchPattern":null,"preventionTips":["Use 'daemon_tool' for general sources and 'local_file' for the read_json alias only.","Do not invent new source.type values without updating the dispatcher.","Add a schema validator at the boundary where model-authored sources enter the daemon."],"tags":["validation","routing","live-artifacts","refresh-source"],"backgroundTag":null,"analyzedSha":"5be4028344c2eb4c667c5a97bda8f750c5597ef7","analyzedAt":"2026-08-12T12:03:58.812Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}