{"record":{"id":"7712b5c17fe0d9a3","repo":"NousResearch/hermes-agent","slug":"noun-is-version-version-this-build-reads-ve","errorCode":null,"errorMessage":"${Noun} is version ${version}; this build reads version ${spec.version}.","messagePattern":"(.+?) is version (.+?); this build reads version (.+?)\\.","errorType":"exception","errorClass":"LoadoutError","httpStatus":null,"severity":"warning","filePath":"apps/desktop/src/lib/loadout.ts","lineNumber":262,"sourceCode":"\n    let framed: Uint8Array\n\n    try {\n      framed = fromBase64Url(raw)\n    } catch {\n      throw new Err(`That doesn't look like a ${noun}.`)\n    }\n\n    if (framed.length <= HEAD_BYTES) {\n      throw new Err(`${Noun} is too short to be valid.`)\n    }\n\n    const head = new BitReader(framed.subarray(0, HEAD_BYTES))\n    const version = head.uint(8)\n    const storedSum = head.uint(16)\n\n    if (version !== spec.version) {\n      throw new Err(`${Noun} is version ${version}; this build reads version ${spec.version}.`)\n    }\n\n    const payload = framed.subarray(HEAD_BYTES)\n\n    if (checksum16(payload) !== storedSum) {\n      throw new Err(`${Noun} looks corrupted (checksum mismatch).`)\n    }\n\n    try {\n      return spec.read(new BitReader(inflateSync(payload)))\n    } catch (err) {\n      throw new Err(err instanceof Error ? `${Noun} is malformed: ${err.message}` : `${Noun} is malformed.`)\n    }\n  }\n\n  return { decode, encode }\n}\n","sourceCodeStart":244,"sourceCodeEnd":280,"githubUrl":"https://github.com/NousResearch/hermes-agent/blob/c896c09c42910c584c4c7d2325b58c14713ea42c/apps/desktop/src/lib/loadout.ts#L244-L280","documentation":"Thrown by the loadout codec's decode() in apps/desktop/src/lib/loadout.ts:262 when the 8-bit version in the frame header does not equal the current spec.version. Every loadout spec versions its bit layout precisely so old codes fail this explicit, readable check instead of misreading bits (which would produce garbage or the 'loadout truncated' RangeError). The message names both the code's version and the version this build reads.","triggerScenarios":"Decoding a code produced by an older build whose spec.version was lower; decoding a code from a NEWER build (version higher than local); forgetting to bump spec.version after changing the read/write schema, so old codes shift into misalignment instead of failing here.","commonSituations":"Sharing codes across app versions or with teammates on older releases; schema evolution (a field added/removed/resized) without a version bump; archived codes pasted after a format change.","solutions":["Regenerate the share code on the current build and share the new one.","If you changed the layout in spec code, bump spec.version in the same commit — that is the whole mechanism.","To support old codes, keep parallel read specs keyed by version and dispatch after parsing the header.","Update the receiving app to a build whose spec.version matches the code's producer."],"exampleFix":"// before — layout changed, version not bumped: old codes decode as garbage\nwrite: w => { w.uint(mode, 2); w.uint(flags, 4) }\n\n// after — bump version with any layout change\nexport const skillsSpec = createLoadout({\n  version: 2,\n  // ...\n})","handlingStrategy":"try-catch","validationCode":"// producer/consumer agreement check in dev builds\nif (spec.version !== EXPECTED_SHARE_VERSION) throw new Error('codec/spec version drift — bump together')","typeGuard":null,"tryCatchPattern":"try { const v = decode(code) } catch (e) {\n  if (e instanceof Err && /version/.test(e.message)) { promptRegenerateCode(); return null }\n  throw e\n}","preventionTips":["Bump spec.version in the same commit as any layout change — this is the codec's core contract","Keep old-version read specs if backward compatibility is required","Regenerate and redistribute codes after upgrades","Never 'patch' a version mismatch by widening bit fields"],"tags":["desktop","loadout","versioning","share-codes","schema"],"backgroundTag":null,"analyzedSha":"c896c09c42910c584c4c7d2325b58c14713ea42c","analyzedAt":"2026-08-14T17:18:01.089Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}