nexu-io/open-design · error · Error
unsupported local daemon refresh tool: ${options.source.tool
Error message
unsupported local daemon refresh tool: ${options.source.toolName} What it means
Thrown by executeLocalDaemonRefreshSource when source.type is 'daemon_tool' but source.toolName is not in the recognized set (validated by isLocalDaemonRefreshToolName). The placeholder '<missing>' is interpolated when toolName is undefined/null, signalling that the field was omitted entirely rather than mis-spelled.
Source
Thrown at apps/daemon/src/live-artifacts/refresh.ts:726
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
- Use one of the registered tool names exactly: 'project_files.search', 'project_files.read_json', 'git.summary', 'public_github_repository_metric'.
- If toolName is missing, add it explicitly to the source object.
- When adding a new tool, register it in isLocalDaemonRefreshToolName AND add a case to the switch in executeLocalDaemonRefreshSource; both must change together.
Example fix
// before
source: { type: 'daemon_tool', toolName: 'github_metric', input: {...} }
// after
source: { type: 'daemon_tool', toolName: 'public_github_repository_metric', input: {...} } Defensive patterns
Strategy: validation
Validate before calling
const KNOWN_TOOLS = new Set(['project_files.search','project_files.read_json','git.summary','public_github_repository_metric']);
function assertRefreshTool(t: unknown): asserts t is string {
if (typeof t !== 'string' || !KNOWN_TOOLS.has(t)) throw new Error(`unknown refresh tool: ${String(t)}`);
} Type guard
function isKnownRefreshTool(v: unknown): v is string {
return typeof v === 'string' && new Set(['project_files.search','project_files.read_json','git.summary','public_github_repository_metric']).has(v);
} Prevention
- Always set toolName explicitly on daemon_tool sources; don't rely on defaults.
- Cross-check tool names against the dispatcher when refactoring.
- Register new tools in both isLocalDaemonRefreshToolName and the switch.
When it happens
Trigger: source = { type: 'daemon_tool' } (no toolName); source = { type: 'daemon_tool', toolName: 'github.metric' }; source = { type: 'daemon_tool', toolName: 'files.read' }; toolName uses a retired or future name not yet registered.
Common situations: Model invents a plausible tool name not in the supported list; copy-paste left toolName out; refactor renamed a tool but old payloads still reference it; tool name typo or case mismatch (the registry is case-sensitive).
Related errors
- unsupported local_file refresh tool: ${toolName}
- local daemon refresh sources require source.type daemon_tool
- connector refresh source requires connector metadata
- ${field} must be a dot-separated JSON path
- public_github_repository_metric input.url must be a valid UR
AI-assisted analysis of nexu-io/open-design@5be4028344 (2026-08-12).
Data as JSON: /api/errors/7a55d18de0fa090d.
Report an issue: GitHub.