nexu-io/open-design · error · Error

local daemon refresh sources require source.type daemon_tool

Error message

local daemon refresh sources require source.type daemon_tool or local_file

What it means

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.

Source

Thrown at apps/daemon/src/live-artifacts/refresh.ts:723

export async function executeLocalDaemonRefreshSource(options: ExecuteLocalDaemonRefreshSourceOptions): Promise<BoundedJsonObject> {
  if (options.source.type === 'local_file') {
    const toolName = options.source.toolName ?? 'project_files.read_json';
    if (toolName !== 'project_files.read_json') {
      throw new Error(`unsupported local_file refresh tool: ${toolName}`);
    }
    return executeProjectFilesReadJson({
      ...options,
      source: {
        ...options.source,
        type: 'daemon_tool',
        toolName,
      },
    });
  }

  if (options.source.type !== 'daemon_tool') {
    throw new Error('local daemon refresh sources require source.type daemon_tool or local_file');
  }
  if (!isLocalDaemonRefreshToolName(options.source.toolName)) {
    throw new Error(`unsupported local daemon refresh tool: ${options.source.toolName ?? '<missing>'}`);
  }

  switch (options.source.toolName) {
    case 'project_files.search':
      return executeProjectFilesSearch(options);
    case 'project_files.read_json':
      return executeProjectFilesReadJson(options);
    case 'git.summary':
      return executeGitSummary(options);
    case 'public_github_repository_metric':
      return executePublicGithubRepositoryMetric(options);
  }
}

View on GitHub (pinned to 5be4028344)

Solutions

  1. Set source.type to 'daemon_tool' (preferred for general use) or 'local_file' (read_json alias).
  2. Confirm there is no third supported type — do not invent one.
  3. If extending the dispatcher to a new type, update isLocalDaemonRefreshToolName and the switch in executeLocalDaemonRefreshSource together.

Example fix

// before
source: { type: 'http', toolName: '...', input: {...} }
// after
source: { type: 'daemon_tool', toolName: '...', input: {...} }
Defensive patterns

Strategy: validation

Validate before calling

const REFRESH_TYPES = new Set(['local_file', 'daemon_tool']);
function assertRefreshType(t: unknown): asserts t is 'local_file' | 'daemon_tool' {
  if (!REFRESH_TYPES.has(t as string)) throw new Error('unsupported refresh source.type');
}

Type guard

function isRefreshSourceType(v: unknown): v is 'local_file' | 'daemon_tool' {
  return v === 'local_file' || v === 'daemon_tool';
}

Prevention

When it happens

Trigger: source.type is 'http', 'webhook', 'cron', undefined, 'remote', or a typo like 'daemon-tool' or 'localfile'.

Common situations: 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.

Related errors


AI-assisted analysis of nexu-io/open-design@5be4028344 (2026-08-12). Data as JSON: /api/errors/895fcf4c89c99e39. Report an issue: GitHub.