{"record":{"id":"8dff63dd0874b903","repo":"affaan-m/ECC","slug":"gate-variant-missing","errorCode":"gate.variant_missing","errorMessage":"variant.json missing in ${resolved}","messagePattern":"variant\\.json missing in (.+?)","errorType":"exception","errorClass":"GateError","httpStatus":null,"severity":"error","filePath":"scripts/lib/eval-harness/gate.js","lineNumber":116,"sourceCode":"function digestDir(dir) {\n  const hash = crypto.createHash('sha256');\n  for (const relative of listFiles(dir)) {\n    hash.update(relative);\n    hash.update('\\0');\n    hash.update(readRegularFile(path.join(dir, relative)));\n    hash.update('\\0');\n  }\n  return hash.digest('hex');\n}\n\nfunction loadVariant(dir) {\n  const resolved = fs.realpathSync(path.resolve(dir));\n  const manifestPath = path.join(resolved, 'variant.json');\n  let manifestBytes;\n  try {\n    manifestBytes = readRegularFile(manifestPath, 'utf8');\n  } catch (error) {\n    if (error.code === 'ENOENT') throw new GateError('gate.variant_missing', `variant.json missing in ${resolved}`);\n    throw error;\n  }\n  const manifest = JSON.parse(manifestBytes);\n  if (typeof manifest.name !== 'string' || !/^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$/.test(manifest.name) || !envelope.EFFECT_CLASSES.includes(manifest.effect_class)) {\n    throw new GateError('gate.variant_invalid', `variant.json in ${resolved} needs name and a valid effect_class`);\n  }\n  const entry = manifest.entry === undefined ? 'run.js' : manifest.entry;\n  if (typeof entry !== 'string' || !entry || path.isAbsolute(entry) || path.win32.isAbsolute(entry) || entry.includes('\\\\') || entry.split('/').includes('..')) {\n    throw new GateError('gate.variant_invalid', 'entry must be a relative regular file within the variant');\n  }\n  const entryPath = path.resolve(resolved, entry);\n  const relative = path.relative(resolved, entryPath);\n  if (!relative || relative.startsWith('..' + path.sep) || path.isAbsolute(relative) || !listFiles(resolved).includes(relative.split(path.sep).join('/')) || !fs.lstatSync(entryPath).isFile()) {\n    throw new GateError('gate.variant_invalid', 'entry must be covered by the variant digest');\n  }\n  return { dir: resolved, name: manifest.name, effect_class: manifest.effect_class, entry: relative, digest: digestDir(resolved) };\n}\n","sourceCodeStart":98,"sourceCodeEnd":134,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/scripts/lib/eval-harness/gate.js#L98-L134","documentation":"loadVariant resolves the variant directory, looks for variant.json inside it, and when that file does not exist (ENOENT) throws GateError('gate.variant_missing') including the resolved directory. Every variant capsule must contain a variant.json manifest describing name, effect_class, and entry.","triggerScenarios":"Calling loadVariant on a directory without variant.json; passing the wrong directory (e.g. the capsule root or a parent); the manifest was deleted, renamed, or never generated.","commonSituations":"Typo'd path to the variant dir; a fresh clone where variants were never generated; a script that writes manifest to a different filename (variants.json, manifest.json); running the gate from the wrong working directory with a relative path.","solutions":["Confirm the directory contains variant.json (`ls <dir>/variant.json`); create or regenerate it if missing.","Check the path passed to loadVariant points at the variant directory itself, not its parent or the capsule root.","Regenerate the variant from the capsule source so the manifest is emitted.","Run the gate from the expected working directory or pass an absolute path."],"exampleFix":"// before\nloadVariant('./variants')            // parent dir, no manifest inside\n// after\nloadVariant('./variants/baseline')   // contains variant.json","handlingStrategy":"try-catch","validationCode":"const fs = require('fs'), path = require('path');\nfunction variantManifestExists(dir) {\n  return fs.existsSync(path.join(path.resolve(dir), 'variant.json'));\n}\nif (!variantManifestExists(dir)) throw new Error(`variant.json missing in ${path.resolve(dir)}`);","typeGuard":"function isDirWithManifest(p) {\n  try {\n    return require('fs').statSync(p).isDirectory() &&\n      require('fs').statSync(require('path').join(p, 'variant.json')).isFile();\n  } catch { return false; }\n}","tryCatchPattern":"try {\n  const variant = loadVariant(dir);\n} catch (e) {\n  if (e.code === 'gate.variant_missing') {\n    console.error(`${e.message} — regenerate the variant or fix the path`);\n  } else throw e;\n}","preventionTips":["Always pass the variant directory itself, not its parent.","Generate variant.json with the capsule tooling; never delete it manually.","Use absolute paths or run the gate from a known working directory.","Add a preflight existence check in CI before gate runs."],"tags":["filesystem","config","eval-harness"],"backgroundTag":"file-not-found","analyzedSha":"8321021c54d670126ce3b2969d5deb880b4b0c2a","analyzedAt":"2026-09-16T10:08:13.343Z","contentChangedAt":"2026-09-16T10:08:13.343Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}