nexu-io/open-design · error
project_files.read_json requires input.path
Error message
project_files.read_json requires input.path
What it means
selectJsonPath (refresh.ts:524-528) resolves the file path for project_files.read_json by trying input.path, then input.file, then input.name (each via optionalString). If none yields a string, it throws, because the tool cannot locate a file without a path.
Source
Thrown at apps/daemon/src/live-artifacts/refresh.ts:526
return { dataJson: asBoundedRefreshOutput(dataJson) };
}
function optionalString(value: BoundedJsonValue | undefined, field: string): string | undefined {
if (value === undefined) return undefined;
if (typeof value !== 'string') throw new Error(`${field} must be a string`);
return value;
}
function optionalPositiveInteger(value: BoundedJsonValue | undefined, field: string, defaultValue: number, maxValue: number): number {
if (value === undefined) return defaultValue;
if (!Number.isSafeInteger(value) || typeof value !== 'number' || value < 1) throw new Error(`${field} must be a positive integer`);
return Math.min(value, maxValue);
}
function selectJsonPath(input: ProjectFilesReadJsonInput): string {
const rawPath = optionalString(input.path, 'input.path') ?? optionalString(input.file, 'input.file') ?? optionalString(input.name, 'input.name');
if (rawPath === undefined) throw new Error('project_files.read_json requires input.path');
return validateProjectPath(rawPath);
}
function compactTextPreview(text: string, query: string | undefined): string {
const normalized = text.replace(/\s+/g, ' ').trim();
if (normalized.length <= 240) return normalized;
if (query === undefined || query.trim().length === 0) return `${normalized.slice(0, 240)}…`;
const index = normalized.toLowerCase().indexOf(query.toLowerCase());
if (index < 0) return `${normalized.slice(0, 240)}…`;
const start = Math.max(0, index - 80);
return `${start > 0 ? '…' : ''}${normalized.slice(start, start + 240)}…`;
}
function isTextLikeFile(file: { kind?: string; mime?: string; name: string }): boolean {
return file.kind === 'code' || file.kind === 'text' || file.kind === 'html' || file.mime?.startsWith('text/') === true || file.name.endsWith('.json');
}
async function executeProjectFilesSearch(options: ExecuteLocalDaemonRefreshSourceOptions): Promise<BoundedJsonObject> {View on GitHub (pinned to 5be4028344)
Solutions
- Set input.path to the project-relative JSON file path (e.g. { path: 'package.json' }).
- If integrating via the sourceJson contract, ensure the path field name matches the schema.
- Validate that at least one of path/file/name is a string before triggering refresh.
Example fix
// before
const input = {};
// throws `project_files.read_json requires input.path`
// after
const input = { path: 'metrics/package.json' }; Defensive patterns
Strategy: validation
Validate before calling
function resolveReadJsonPath(input: { path?: unknown; file?: unknown; name?: unknown }): string {
const p = input.path ?? input.file ?? input.name;
if (typeof p !== 'string' || p.length === 0) {
throw new Error('project_files.read_json requires input.path');
}
return p;
} Type guard
function hasReadJsonPath(input: unknown): input is { path: string } {
return typeof input === 'object' && input !== null
&& typeof (input as { path?: unknown }).path === 'string';
} Prevention
- Always set input.path when constructing a project_files.read_json source.
- Use the typed ProjectFilesReadJsonInput so missing fields surface at compile time.
- Validate source.input shape before scheduling a refresh.
When it happens
Trigger: A project_files.read_json source.input contains none of path/file/name, or contains them as non-string values (in which case optionalString throws 'must be a string' first).
Common situations: Source.input is an empty object; the path key was misspelled (e.g. 'filePath'); a default-constructed source never set the path; a migration renamed the field.
Related errors
- ${field} must be a string
- ${field} must be a positive integer
- project_files.read_json only supports .json files
- project_files.read_json does not follow symlinks
- project_files.read_json path escapes project dir
AI-assisted analysis of nexu-io/open-design@5be4028344 (2026-08-12).
Data as JSON: /api/errors/7c6c7514c8d57012.
Report an issue: GitHub.