nexu-io/open-design · error · Error
unsupported local_file refresh tool: ${toolName}
Error message
unsupported local_file refresh tool: ${toolName} What it means
Thrown by executeLocalDaemonRefreshSource when source.type is 'local_file' but source.toolName is set to anything other than 'project_files.read_json' (the only currently-supported local_file tool; toolName defaults to project_files.read_json when omitted). Any other toolName under local_file is rejected before dispatch because no handler exists.
Source
Thrown at apps/daemon/src/live-artifacts/refresh.ts:710
if (!response.ok) {
throw new Error(`public_github_repository_metric request failed with ${response.status}`);
}
const parsed = await response.json() as Record<string, unknown>;
const output: BoundedJsonObject = { toolName: 'public_github_repository_metric' };
for (const field of selectGithubFields(input)) {
const value = parsed[field];
if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean' || value === null) {
output[field] = value;
}
}
return asBoundedRefreshOutput(output);
}
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>'}`);
}
View on GitHub (pinned to 5be4028344)
Solutions
- For non-read_json tools, set source.type to 'daemon_tool' (the general case).
- If you want JSON-from-file behavior, either omit toolName or set it explicitly to 'project_files.read_json'.
- Re-check the supported matrix: local_file -> project_files.read_json only; daemon_tool -> project_files.search, project_files.read_json, git.summary, public_github_repository_metric.
Example fix
// before
source: { type: 'local_file', toolName: 'git.summary', input: {...} }
// after
source: { type: 'daemon_tool', toolName: 'git.summary', input: {...} } Defensive patterns
Strategy: validation
Validate before calling
function coerceLocalFileSource(s: { type: string; toolName?: string }) {
if (s.type === 'local_file' && s.toolName && s.toolName !== 'project_files.read_json') {
return { ...s, type: 'daemon_tool' };
}
return s;
} Type guard
function isLocalFileReadJson(s: unknown): boolean {
return typeof s === 'object' && s !== null
&& (s as any).type === 'local_file'
&& ((s as any).toolName ?? 'project_files.read_json') === 'project_files.read_json';
} Prevention
- Remember local_file is an alias for project_files.read_json only.
- For all other tools, use type 'daemon_tool'.
- Validate source shape against a schema before queuing a refresh.
When it happens
Trigger: source = { type: 'local_file', toolName: 'git.summary' }; source = { type: 'local_file', toolName: 'project_files.search' }; source = { type: 'local_file', toolName: 'public_github_repository_metric' }.
Common situations: Model assumes any daemon tool can run against a local file source; config copy-pasted from a daemon_tool entry but type left as local_file; misunderstanding that local_file is a narrow alias only for read_json.
Related errors
- local daemon refresh sources require source.type daemon_tool
- unsupported local daemon refresh tool: ${options.source.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/987dd89c8f543c54.
Report an issue: GitHub.