{"record":{"id":"5593bcb0549f8c42","repo":"abhigyanpatwari/GitNexus","slug":"benchmark-index-metadata-is-missing-indexedat-or-l","errorCode":null,"errorMessage":"benchmark index metadata is missing indexedAt or lastCommit","messagePattern":"benchmark index metadata is missing indexedAt or lastCommit","errorType":"exception","errorClass":"SandboxError","httpStatus":null,"severity":"error","filePath":"eval/workflow_bench/runner.py","lineNumber":354,"sourceCode":"    \"\"\"Create a one-clone registry that cannot route MCP to any host repo.\"\"\"\n\n    metadata_path = worktree / \".gitnexus\" / \"gitnexus.json\"\n    if not metadata_path.exists():\n        metadata_path = worktree / \".gitnexus\" / \"meta.json\"\n    mode = metadata_path.lstat().st_mode\n    if stat.S_ISLNK(mode) or not stat.S_ISREG(mode):\n        raise SandboxError(f\"benchmark index metadata must be regular and non-symlink: {metadata_path}\")\n    raw = _bounded_regular_bytes(metadata_path, limit=2 * 1024 * 1024)\n    try:\n        metadata = json.loads(raw)\n    except json.JSONDecodeError as exc:\n        raise SandboxError(f\"benchmark index metadata is malformed: {metadata_path}\") from exc\n    if not isinstance(metadata, dict):\n        raise SandboxError(f\"benchmark index metadata must be an object: {metadata_path}\")\n    indexed_at = metadata.get(\"indexedAt\")\n    last_commit = metadata.get(\"lastCommit\")\n    if not isinstance(indexed_at, str) or not indexed_at or not isinstance(last_commit, str) or not last_commit:\n        raise SandboxError(\"benchmark index metadata is missing indexedAt or lastCommit\")\n\n    parent = parent.expanduser().absolute()\n    registry = Path(tempfile.mkdtemp(prefix=\"wfbench-registry-\", dir=parent))\n    registry.chmod(0o700)\n    entry: dict[str, Any] = {\n        \"name\": \"benchmark-target\",\n        \"path\": SANDBOX_WORKSPACE,\n        \"storagePath\": f\"{SANDBOX_WORKSPACE}/.gitnexus\",\n        \"indexedAt\": indexed_at,\n        \"lastCommit\": last_commit,\n    }\n    for field in (\"remoteUrl\", \"stats\", \"branch\"):\n        if field in metadata:\n            entry[field] = metadata[field]\n    registry_file = registry / \"registry.json\"\n    descriptor = os.open(\n        registry_file,\n        os.O_WRONLY | os.O_CREAT | os.O_EXCL | getattr(os, \"O_NOFOLLOW\", 0),","sourceCodeStart":336,"sourceCodeEnd":372,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/d540b00184d71a896261ee02670da9a92d59d8f7/eval/workflow_bench/runner.py#L336-L372","documentation":"Raised by isolated_gitnexus_registry_mount when the metadata object is missing the indexedAt or lastCommit fields, or either is not a non-empty string. These two fields are copied verbatim into the isolated registry entry to pin the index provenance; without both, the sandboxed MCP cannot trust which index/commit it is routing to, so staging aborts.","triggerScenarios":"metadata is a dict but metadata.get('indexedAt') or metadata.get('lastCommit') is missing, None, empty, or non-string — e.g. the indexer wrote the object without these provenance keys.","commonSituations":"An older indexer version that did not emit indexedAt/lastCommit; a manually constructed descriptor missing the keys; a field rename in a newer index format; values written as numbers/null instead of strings.","solutions":["Print the keys present: `python3 -c \"import json; d=json.load(open('<worktree>/.gitnexus/gitnexus.json')); print(d.get('indexedAt'), d.get('lastCommit'))\"`.","If missing or empty, regenerate the index with a current indexer so both provenance strings are written.","If manually authoring the descriptor, include non-empty string values for both indexedAt and lastCommit.","Upgrade/downgrade mismatch: align the indexer version with what the harness expects."],"exampleFix":"// before — descriptor lacks provenance fields\n{ \"stats\": {\"symbols\": 100} }\n// after — regenerate so indexedAt + lastCommit are present\nrm <worktree>/.gitnexus/gitnexus.json\nnode .gitnexus/run.cjs analyze --index-only\n// resulting object includes: { \"indexedAt\": \"2026-...\", \"lastCommit\": \"abc123...\" }","handlingStrategy":"validation","validationCode":"import json\nfrom pathlib import Path\n\nd = json.loads((worktree / '.gitnexus' / 'gitnexus.json').read_bytes())\nindexed_at, last_commit = d.get('indexedAt'), d.get('lastCommit')\nassert isinstance(indexed_at, str) and indexed_at, 'missing/empty indexedAt'\nassert isinstance(last_commit, str) and last_commit, 'missing/empty lastCommit'","typeGuard":"def has_provenance(d: object) -> bool:\n    return (\n        isinstance(d, dict)\n        and isinstance(d.get('indexedAt'), str) and bool(d['indexedAt'])\n        and isinstance(d.get('lastCommit'), str) and bool(d['lastCommit'])\n    )","tryCatchPattern":"from .proposer_sandbox import SandboxError\n\ntry:\n    mount = isolated_gitnexus_registry_mount(worktree, parent)\nexcept SandboxError as exc:\n    if 'missing indexedAt or lastCommit' in str(exc):\n        # regenerate the index with a current indexer so provenance is written\n        raise\n    raise","preventionTips":["Use an indexer version that emits indexedAt and lastCommit.","Never strip provenance fields from the descriptor.","Validate both fields are non-empty strings after indexing."],"tags":["sandbox","registry","gitnexus","validation","provenance"],"backgroundTag":null,"analyzedSha":"d540b00184d71a896261ee02670da9a92d59d8f7","analyzedAt":"2026-08-12T19:50:25.132Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}