jackwener/OpenCLI · error · CliError
EMPTY_RESPONSE
EMPTY_RESPONSE
Error message
EMPTY_RESPONSE
What it means
The yollomi restore command throws EMPTY_RESPONSE when /api/ai/photo-restoration returns no restored image. It reads data.image or data.images[0]; absence of both aborts the command before downloading.
Source
Thrown at clis/yollomi/restore.js:27
cli({
site: 'yollomi',
name: 'restore',
access: 'write',
description: 'Restore old or damaged photos with AI (4 credits)',
domain: YOLLOMI_DOMAIN,
strategy: Strategy.COOKIE,
args: [
{ name: 'image', positional: true, required: true, help: 'Image URL to restore' },
{ name: 'output', default: './yollomi-output', help: 'Output directory' },
{ name: 'no-download', type: 'boolean', default: false, help: 'Only show URL' },
],
columns: ['status', 'file', 'size', 'url'],
func: async (page, kwargs) => {
log.status('Restoring photo...');
const data = await yollomiPost(page, '/api/ai/photo-restoration', { imageUrl: kwargs.image });
const url = data.image || (data.images?.[0]);
if (!url)
throw new CliError('EMPTY_RESPONSE', 'No result', 'Check the input image');
if (kwargs['no-download'])
return [{ status: 'restored', file: '-', size: '-', url }];
try {
const filename = `yollomi_restored_${Date.now()}.jpg`;
const { path: fp, size } = await downloadOutput(url, kwargs.output, filename);
return [{ status: 'saved', file: path.relative('.', fp), size: fmtBytes(size), url }];
}
catch {
return [{ status: 'download-failed', file: '-', size: '-', url }];
}
},
});
View on GitHub (pinned to 49907e53dc)
Solutions
- Check the input image is a valid, publicly reachable URL (per the hint)
- Upload local files first with `yollomi upload` and use the returned URL
- Retry — transient processing failures can return empty bodies
- Log the raw response to look for ignored error fields
- Adjust field extraction if the API response shape changed
Example fix
// before
const url = data.image || (data.images?.[0]);
if (!url) throw new CliError('EMPTY_RESPONSE', 'No result', 'Check the input image');
// after
if (data.error) throw new CliError('API_ERROR', data.error, 'Check restoration API response');
const url = data.image || data.restored || (data.images?.[0]);
if (!url) throw new CliError('EMPTY_RESPONSE', 'No result', 'Check the input image'); Defensive patterns
Strategy: validation
Validate before calling
const ok = await fetch(kwargs.image, { method: 'HEAD' });
if (!ok.ok) throw new Error(`input image not reachable: ${ok.status}`);
const type = ok.headers.get('content-type') || '';
if (!type.startsWith('image/')) throw new Error(`not an image: ${type}`); Type guard
function hasRestoredImage(d) {
return d != null && (typeof d.image === 'string' || (Array.isArray(d.images) && typeof d.images[0] === 'string'));
} Try / catch
try {
const rows = await opencli.yollomi.restore({ image: url });
} catch (e) {
if (e.code === 'EMPTY_RESPONSE') {
// try a higher-quality source image, or retry once for transient failures
console.error(`${e.message}: ${e.hint}`);
} else throw e;
} Prevention
- Provide the best-quality source photo available; heavily degraded scans may yield nothing
- Use a public, stable URL (not expired signed links or local paths)
- HEAD-check the URL before running
- Retry once — restoration can fail transiently server-side
When it happens
Trigger: POSTing { imageUrl: kwargs.image } where the photo cannot be fetched/processed server-side (dead URL, unsupported format, image too large/degraded), or the response no longer contains image/images fields.
Common situations: Old scanned photos too degraded for the model; expired or private image URLs; passing a local path instead of a URL; site API schema change after an update.
Related errors
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/0bd4a0a524a70565.
Report an issue: GitHub.