jackwener/OpenCLI · error · CommandExecutionError
Midjourney reference upload fallback failed
Error message
Midjourney reference upload fallback failed: ${result?.reason || 'unknown error'} What it means
Thrown when the page-level fallback upload path (dispatching native/input events on a file input inside the browser) returns a non-ok result. The evaluate returns {ok:false, reason} and the CLI surfaces the reason, defaulting to 'unknown error' when none is provided. It indicates the simulated file drop into Midjourney's reference input did not complete.
Solutions
- Inspect result?.reason in the thrown message and fix the underlying in-page condition (missing input, disabled form).
- Update the file input selector / event dispatch logic to match the current Midjourney composer DOM.
- Ensure the browser Bridge (page.evaluate with native events) is up to date and the page is fully loaded before uploading.
- Retry the upload after reloading the Midjourney page.
Example fix
// before
if (!result?.ok) throw new CommandExecutionError(`Midjourney reference upload fallback failed: ${result?.reason || 'unknown error'}`);
// after
if (!result?.ok) {
await page.reload();
await page.wait(2);
throw new CommandExecutionError(`Midjourney reference upload fallback failed: ${result?.reason || 'unknown error'}`);
} Defensive patterns
Strategy: retry
Validate before calling
const probe = await page.evaluate(() => !!document.querySelector('input[type=file]'));
if (!probe) throw new Error('No file input available for fallback upload'); Type guard
function isUploadResult(r) { return r && typeof r === 'object' && typeof r.ok === 'boolean'; } Try / catch
try {
await uploadReferenceLibrary(page, paths);
} catch (err) {
if (String(err.message).includes('fallback failed')) {
await page.reload();
await uploadReferenceLibrary(page, paths);
} else throw err;
} Prevention
- Keep the Browser Bridge extension updated
- Ensure the page is fully loaded before uploading
- Log result.reason for diagnostics
- Reload the page between retries
When it happens
Trigger: Calling the fallback upload path after the primary drag-and-drop upload fails; page.evaluate dispatchEvent/natural file transfer returns {ok:false, reason:...} or returns null/undefined.
Common situations: Midjourney UI changed so the file input selector no longer matches; the injected DataTransfer/natural event pipeline is blocked; browser Bridge evaluate returns undefined; uploadKey global was already cleaned up by a concurrent run.
Related errors
- Could not locate Midjourney
- Appending images failed
- Browser Bridge native click support is required
- composer fill was not verified
- Could not set Midjourney
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/b66fcbd86a6c756a.
Report an issue: GitHub.
Appendix: source
Thrown at clis/midjourney/utils.js:1040
const transfer = new DataTransfer();
for (const item of window[key] || []) {
const binary = atob(item.chunks.join(''));
const bytes = new Uint8Array(binary.length);
for (let index = 0; index < binary.length; index += 1) bytes[index] = binary.charCodeAt(index);
transfer.items.add(new File([bytes], item.name, { type: item.mime }));
}
input.files = transfer.files;
const nativeEvent = new Event('change', { bubbles: true });
const propsKey = Object.keys(input).find((key) => key.startsWith('__reactProps$'));
if (propsKey && typeof input[propsKey]?.onChange === 'function') {
input[propsKey].onChange({ target: input, currentTarget: input, nativeEvent });
} else {
input.dispatchEvent(nativeEvent);
input.dispatchEvent(new Event('input', { bubbles: true }));
}
return { ok: true, count: transfer.files.length };
}, uploadKey));
if (!result?.ok) throw new CommandExecutionError(`Midjourney reference upload fallback failed: ${result?.reason || 'unknown error'}`);
} finally {
await page.evaluate((key) => {
delete window[key];
return true;
}, uploadKey).catch(() => {});
}
}
async function markReferenceTarget(page, sourceUrl, slotLabel) {
const result = unwrapEvaluateResult(await page.evaluate((url, label) => {
document.querySelectorAll('[data-opencli-ref-source],[data-opencli-ref-target]').forEach((el) => {
el.removeAttribute('data-opencli-ref-source');
el.removeAttribute('data-opencli-ref-target');
});
const source = [...document.querySelectorAll('img[src]')].find((img) => img.src === url);
const labelNode = [...document.querySelectorAll('div,span')].find((node) => node.children.length === 0 && node.textContent?.trim() === label);
if (!source || !labelNode) return { ok: false, source: Boolean(source), target: Boolean(labelNode) };
let target = labelNode.parentElement;View on GitHub (pinned to 49907e53dc)