Mintplex-Labs/anything-llm · critical · Error

EFI vars template not found

Error message

EFI vars template not found: ${file}
Searched in: ${QEMU_DIST || '(no QEMU_DIST set)'}
Set OPEN_COMPUTER_QEMU_DIR to your QEMU installation directory.

What it means

Thrown by resolveEfiVars() in the open-computer CLI when, on Windows only, the writable EFI variable-store template (edk2-i386-vars.fd for x86_64 guests, edk2-arm-vars.fd for aarch64) is missing from both ${QEMU_DIST}/share/qemu/ and ${QEMU_DIST}/share/. The vars template is copied per-VM as the writable pflash; per the code comment, using the CODE image in the vars slot leaves OVMF without a variable store so the guest never POSTs. The bundled Windows QEMU build ships this file in share/ rather than share/qemu/, hence the two search locations.

Solutions

  1. Copy edk2-i386-vars.fd (x86_64 host) or edk2-arm-vars.fd (arm64 host) into ${QEMU_DIST}/share/ (bundled layout) or ${QEMU_DIST}/share/qemu/
  2. Set OPEN_COMPUTER_QEMU_DIR to a complete QEMU installation that ships both code and vars EDK2 files
  3. Re-download/re-extract the bundled QEMU archive so the full share/ tree is restored
  4. If only an edk2-*-vars.fd from another distro is available, use one matching the same EDK2 build as your code image to avoid pflash format mismatch

Example fix

# before: C:\qemu\share\qemu\ has edk2-x86_64-code.fd but no vars file -> throw
# after: place the vars template where the resolver looks
 cp /usr/share/edk2/ovmf-vars.fd  $OPEN_COMPUTER_QEMU_DIR/share/edk2-i386-vars.fd
# (any blank OVMF/EDK2 vars store works as the template)
Defensive patterns

Strategy: validation

Validate before calling

const fs = require('fs');
const path = require('path');
function efiVarsExists(qemuDir, arch) {
  const file = arch === 'x86_64' ? 'edk2-i386-vars.fd' : 'edk2-arm-vars.fd';
  return [path.join(qemuDir, 'share', 'qemu', file), path.join(qemuDir, 'share', file)]
    .some((p) => fs.existsSync(p));
}

Try / catch

try { vm.start({ efiVars: resolveEfiVars() }); } catch (e) { if (/EFI vars template not found/.test(e.message)) { /* copy the vars .fd into ${QEMU_DIST}/share and restart */ } else throw e; }

Prevention

When it happens

Trigger: Same conditions as the EFI code error but for the vars file: OPEN_COMPUTER_QEMU_DIR or the bundled master/qemu/win-* folder exists (so resolveEfiCode may pass) yet edk2-i386-vars.fd / edk2-arm-vars.fd is absent from share/ and share/qemu/; typically a trimmed QEMU distribution that ships edk2-*-code.fd but not the vars template.

Common situations: Hand-assembled QEMU folder where only the *-code.fd was copied; a QEMU package that splits OVMF vars into a separate firmware package; moving files after first successful boot and losing the template.

Related errors


AI-assisted analysis of Mintplex-Labs/anything-llm@3aec848f28 (2026-08-18). Data as JSON: /api/errors/ebcae030d574919c. Report an issue: GitHub.

Appendix: source

Thrown at open-computer/cli/src/config.ts:108

// not the CODE firmware: copying CODE into the vars slot leaves OVMF without a
// variable store, so it never POSTs and the display stays blank.
export function efiVarsFileName(guestArch: 'aarch64' | 'x86_64' = GUEST_ARCH): string {
  return guestArch === 'x86_64' ? 'edk2-i386-vars.fd' : 'edk2-arm-vars.fd';
}

export function resolveEfiVars(): string {
  const file = efiVarsFileName();
  if (QEMU_DIST) {
    // The bundled Windows build ships the vars template in share/ (not share/qemu/).
    for (const cand of [
      path.join(QEMU_DIST, 'share', 'qemu', file),
      path.join(QEMU_DIST, 'share', file),
    ]) {
      if (fs.existsSync(cand)) return cand;
    }
  }
  if (PLATFORM === 'win32') {
    throw new Error(
      `EFI vars template not found: ${file}\n` +
      `Searched in: ${QEMU_DIST || '(no QEMU_DIST set)'}\n` +
      `Set OPEN_COMPUTER_QEMU_DIR to your QEMU installation directory.`,
    );
  }
  const shareDir = PLATFORM === 'linux' ? '/usr/share/qemu' : '/opt/homebrew/share/qemu';
  return `${shareDir}/${file}`;
}

// Full path to the qemu-img binary
export function resolveQemuImgBinary(): string {
  const binaryName = PLATFORM === 'win32' ? 'qemu-img.exe' : 'qemu-img';
  if (QEMU_DIST) {
    const bundled = path.join(QEMU_DIST, 'bin', binaryName);
    if (fs.existsSync(bundled)) return bundled;
    const direct = path.join(QEMU_DIST, binaryName);
    if (fs.existsSync(direct)) return direct;
  }

View on GitHub (pinned to 3aec848f28)