NousResearch/hermes-agent · warning · LoadoutError

${Noun} is too short to be valid.

Error message

${Noun} is too short to be valid.

What it means

Thrown by the loadout codec's decode() in apps/desktop/src/lib/loadout.ts:254 when the decoded framed bytes are not longer than HEAD_BYTES — the fixed header holding the 8-bit version and 16-bit checksum. A payload that decodes from base64url but is byte-empty or header-sized-or-smaller cannot possibly carry a framed body, so it is rejected before any bit-reading. Distinguishes 'too short' from 'not base64 at all' to give an accurate paste-error message.

Source

Thrown at apps/desktop/src/lib/loadout.ts:254

    // Strip ALL whitespace, not just the ends — a pasted code often picks up soft
    // wraps / newlines, and base64 decoding chokes on any of it.
    const cleaned = code.replace(/\s+/g, '')
    const raw = cleaned.startsWith(spec.prefix) ? cleaned.slice(spec.prefix.length) : cleaned

    if (!raw) {
      throw new Err(`That doesn't look like a ${noun}.`)
    }

    let framed: Uint8Array

    try {
      framed = fromBase64Url(raw)
    } catch {
      throw new Err(`That doesn't look like a ${noun}.`)
    }

    if (framed.length <= HEAD_BYTES) {
      throw new Err(`${Noun} is too short to be valid.`)
    }

    const head = new BitReader(framed.subarray(0, HEAD_BYTES))
    const version = head.uint(8)
    const storedSum = head.uint(16)

    if (version !== spec.version) {
      throw new Err(`${Noun} is version ${version}; this build reads version ${spec.version}.`)
    }

    const payload = framed.subarray(HEAD_BYTES)

    if (checksum16(payload) !== storedSum) {
      throw new Err(`${Noun} looks corrupted (checksum mismatch).`)
    }

    try {
      return spec.read(new BitReader(inflateSync(payload)))

View on GitHub (pinned to c896c09c42)

Solutions

  1. Re-copy the complete code — truncation that preserves base64 validity is the usual cause.
  2. If producing codes programmatically, verify encode() output decodes to more than HEAD_BYTES bytes in a round-trip test.
  3. Check the pasted code against the original length; loadout codes carry real payloads so they are never this short.
  4. Surface the typed Err message in the paste UI.

Example fix

// before
const result = decode(userCode) // header-only code throws here

// after — cheap length sanity before decode
const payloadLen = Math.floor((userCode.replace(/\s+/g, '').length) * 3 / 4)
if (payloadLen <= 4) { showPasteError('Code is incomplete — copy the whole thing'); return }
const result = decode(userCode)
Defensive patterns

Strategy: validation

Validate before calling

function plausibleCodeLength(raw: string, headBytes: number): boolean {
  // base64url chars x 3/4 approximates decoded bytes; require strictly more than the header
  return raw.length * 3 / 4 > headBytes
}

Try / catch

try { const v = decode(input) } catch (e) { if (e instanceof Err && /too short/.test(e.message)) { showPasteError('Code looks incomplete — copy the entire code'); return null } throw e }

Prevention

When it happens

Trigger: A base64url string that decodes to 0–N bytes where N <= HEAD_BYTES (e.g. 'AA' or 'AAA'); a code where the payload was stripped after emission; an encode() bug that framed only the header with an empty body.

Common situations: Truncated pastes that happen to keep valid base64 shape; placeholder/obfuscated codes; test vectors built from header-only buffers; a producer bug emitting prefix+header without a deflated payload.

Related errors


AI-assisted analysis of NousResearch/hermes-agent@c896c09c42 (2026-08-14). Data as JSON: /api/errors/426f1318514c4d02. Report an issue: GitHub.