{"record":{"id":"7c6c7514c8d57012","repo":"nexu-io/open-design","slug":"project-files-read-json-requires-input-path","errorCode":null,"errorMessage":"project_files.read_json requires input.path","messagePattern":"project_files\\.read_json requires input\\.path","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"apps/daemon/src/live-artifacts/refresh.ts","lineNumber":526,"sourceCode":"\n  return { dataJson: asBoundedRefreshOutput(dataJson) };\n}\n\nfunction optionalString(value: BoundedJsonValue | undefined, field: string): string | undefined {\n  if (value === undefined) return undefined;\n  if (typeof value !== 'string') throw new Error(`${field} must be a string`);\n  return value;\n}\n\nfunction optionalPositiveInteger(value: BoundedJsonValue | undefined, field: string, defaultValue: number, maxValue: number): number {\n  if (value === undefined) return defaultValue;\n  if (!Number.isSafeInteger(value) || typeof value !== 'number' || value < 1) throw new Error(`${field} must be a positive integer`);\n  return Math.min(value, maxValue);\n}\n\nfunction selectJsonPath(input: ProjectFilesReadJsonInput): string {\n  const rawPath = optionalString(input.path, 'input.path') ?? optionalString(input.file, 'input.file') ?? optionalString(input.name, 'input.name');\n  if (rawPath === undefined) throw new Error('project_files.read_json requires input.path');\n  return validateProjectPath(rawPath);\n}\n\nfunction compactTextPreview(text: string, query: string | undefined): string {\n  const normalized = text.replace(/\\s+/g, ' ').trim();\n  if (normalized.length <= 240) return normalized;\n  if (query === undefined || query.trim().length === 0) return `${normalized.slice(0, 240)}…`;\n  const index = normalized.toLowerCase().indexOf(query.toLowerCase());\n  if (index < 0) return `${normalized.slice(0, 240)}…`;\n  const start = Math.max(0, index - 80);\n  return `${start > 0 ? '…' : ''}${normalized.slice(start, start + 240)}…`;\n}\n\nfunction isTextLikeFile(file: { kind?: string; mime?: string; name: string }): boolean {\n  return file.kind === 'code' || file.kind === 'text' || file.kind === 'html' || file.mime?.startsWith('text/') === true || file.name.endsWith('.json');\n}\n\nasync function executeProjectFilesSearch(options: ExecuteLocalDaemonRefreshSourceOptions): Promise<BoundedJsonObject> {","sourceCodeStart":508,"sourceCodeEnd":544,"githubUrl":"https://github.com/nexu-io/open-design/blob/5be4028344c2eb4c667c5a97bda8f750c5597ef7/apps/daemon/src/live-artifacts/refresh.ts#L508-L544","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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."],"exampleFix":"// before\nconst input = {};\n// throws `project_files.read_json requires input.path`\n\n// after\nconst input = { path: 'metrics/package.json' };","handlingStrategy":"validation","validationCode":"function resolveReadJsonPath(input: { path?: unknown; file?: unknown; name?: unknown }): string {\n  const p = input.path ?? input.file ?? input.name;\n  if (typeof p !== 'string' || p.length === 0) {\n    throw new Error('project_files.read_json requires input.path');\n  }\n  return p;\n}","typeGuard":"function hasReadJsonPath(input: unknown): input is { path: string } {\n  return typeof input === 'object' && input !== null\n    && typeof (input as { path?: unknown }).path === 'string';\n}","tryCatchPattern":null,"preventionTips":["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."],"tags":["live-artifacts","project-files","input-validation"],"backgroundTag":null,"analyzedSha":"5be4028344c2eb4c667c5a97bda8f750c5597ef7","analyzedAt":"2026-08-12T12:03:58.812Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}