{"record":{"id":"cd98a6c0cf5ac09c","repo":"musistudio/claude-code-router","slug":"input-image-must-be-a-non-empty-regular-file-no-la","errorCode":null,"errorMessage":"Input image must be a non-empty regular file no larger than ${maxInputBytes} bytes.","messagePattern":"Input image must be a non-empty regular file no larger than (.+?) bytes\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/core/src/media/service.ts","lineNumber":528,"sourceCode":"  private cleanup(): void {\n    const now = Date.now();\n    for (const job of this.jobStore.list()) {\n      if (job.artifact && Date.parse(job.artifact.expiresAt) <= now) this.artifactStore.delete(job.artifact);\n    }\n    for (const job of this.jobStore.deleteOlderThan(now - jobRetentionDays * 24 * 60 * 60 * 1000)) this.artifactStore.delete(job.artifact);\n  }\n\n  private validateImages(value: unknown, min: number, max: number): string[] {\n    const raw = typeof value === \"string\" ? [value] : Array.isArray(value) ? value : [];\n    if (raw.length < min || raw.length > max || raw.some((item) => typeof item !== \"string\" || !item.trim())) {\n      throw new Error(`images must contain between ${min} and ${max} local image paths.`);\n    }\n    const roots = mediaInputRoots(this.requireRuntimeConfig().allowedInputRoots);\n    return raw.map((item) => {\n      const resolved = realpathSync(expandHome(String(item).trim()));\n      if (!roots.some((root) => isPathInside(resolved, root))) throw new Error(`Input image is outside allowed roots: ${resolved}`);\n      const stats = statSync(resolved);\n      if (!stats.isFile() || stats.size <= 0 || stats.size > maxInputBytes) throw new Error(`Input image must be a non-empty regular file no larger than ${maxInputBytes} bytes.`);\n      if (!detectMediaType(resolved).mimeType?.startsWith(\"image/\")) throw new Error(`Unsupported input image format: ${resolved}`);\n      return resolved;\n    });\n  }\n\n  private finishCanceled(job: MediaJob, message: string): MediaJob {\n    const next = this.jobStore.update(job.id, {\n      error: { code: \"canceled\", message, retryable: false },\n      finishedAt: new Date().toISOString(),\n      status: \"canceled\"\n    });\n    this.completions.get(job.id)?.resolve(next);\n    this.completions.delete(job.id);\n    return next;\n  }\n\n  private publicJob(job: MediaJob): PublicMediaJob {\n    const { artifact, idempotencyKeyHash: _idempotencyKeyHash, ...rest } = job;","sourceCodeStart":510,"sourceCodeEnd":546,"githubUrl":"https://github.com/musistudio/claude-code-router/blob/99f24806c6a2c660b16e53e95211c517448a6c90/packages/core/src/media/service.ts#L510-L546","documentation":"Each input image must be a regular, non-empty file no larger than maxInputBytes, checked with statSync after path resolution. Directories, empty files, zero-byte truncations, and oversized uploads all fail here.","triggerScenarios":"Passing a directory path, a 0-byte file, a special file, or an image larger than the configured maxInputBytes limit.","commonSituations":"Drag-and-drop created an empty file, download was interrupted, or multi-MB photos/videos exceed the default size cap.","solutions":["Verify the file exists and has size > 0 and <= maxInputBytes before the call","Raise maxInputBytes in runtime config if legitimately large inputs are needed","Ensure the path is a regular file, not a directory or FIFO"],"exampleFix":"// before\nimages: [\"/data/allowed/video.mp4\"]\n// after\nimages: [\"/data/allowed/photo.jpg\"] // size <= maxInputBytes","handlingStrategy":"validation","validationCode":"const st = statSync(p); if (!st.isFile() || st.size === 0 || st.size > maxInputBytes) throw new RangeError(p);","typeGuard":"const isAcceptableImageFile = (st: { isFile(): boolean; size: number }, max: number): boolean => st.isFile() && st.size > 0 && st.size <= max;","tryCatchPattern":"try { await call(); } catch (e) { if (e instanceof Error && e.message.includes(\"non-empty regular file\")) return invalidFile(); throw e; }","preventionTips":["Pre-check file size before upload","Raise maxInputBytes deliberately when needed"],"tags":["media","file-size","validation"],"backgroundTag":"file-too-large","analyzedSha":"99f24806c6a2c660b16e53e95211c517448a6c90","analyzedAt":"2026-08-27T04:11:01.184Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}