{"record":{"id":"d569019e7a4310f1","repo":"stablyai/orca","slug":"verify-packaged-plugin-resources-bundled-plugin","errorCode":null,"errorMessage":"[verify-packaged-plugin-resources] bundled plugin index is empty or invalid","messagePattern":"\\[verify-packaged-plugin-resources\\] bundled plugin index is empty or invalid","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"config/scripts/verify-packaged-plugin-resources.cjs","lineNumber":78,"sourceCode":"function readJsonFile(path, label) {\n  try {\n    return JSON.parse(readFileSync(path, 'utf8'))\n  } catch (error) {\n    throw new Error(\n      `[verify-packaged-plugin-resources] invalid ${label} at ${path}: ${error instanceof Error ? error.message : String(error)}`\n    )\n  }\n}\n\nfunction verifyPackagedPluginResources(resourcesDir) {\n  const launchRoot = join(resourcesDir, 'plugins', 'launch')\n  if (!statSync(launchRoot).isDirectory()) {\n    throw new Error(`[verify-packaged-plugin-resources] missing launch directory at ${launchRoot}`)\n  }\n  const index = readJsonFile(join(launchRoot, 'bundled-plugins.json'), 'bundled plugin index')\n  readJsonFile(join(launchRoot, 'orca-marketplace.json'), 'marketplace index')\n  if (index?.version !== 1 || !Array.isArray(index.plugins) || index.plugins.length === 0) {\n    throw new Error('[verify-packaged-plugin-resources] bundled plugin index is empty or invalid')\n  }\n  const resolvedRoot = resolve(launchRoot)\n  for (const entry of index.plugins) {\n    if (\n      typeof entry?.pluginKey !== 'string' ||\n      typeof entry.path !== 'string' ||\n      !/^[0-9a-f]{64}$/.test(entry.contentHash)\n    ) {\n      throw new Error('[verify-packaged-plugin-resources] bundled plugin entry is invalid')\n    }\n    const pluginRoot = resolve(launchRoot, entry.path)\n    const fromRoot = relative(resolvedRoot, pluginRoot)\n    if (!fromRoot || fromRoot === '..' || fromRoot.startsWith(`..${sep}`) || isAbsolute(fromRoot)) {\n      throw new Error('[verify-packaged-plugin-resources] bundled plugin path escapes launch root')\n    }\n    const manifest = readJsonFile(join(pluginRoot, 'orca-plugin.json'), 'plugin manifest')\n    if (`${manifest.publisher}.${manifest.id}` !== entry.pluginKey) {\n      throw new Error(","sourceCodeStart":60,"sourceCodeEnd":96,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/config/scripts/verify-packaged-plugin-resources.cjs#L60-L96","documentation":"Thrown by the packaged plugin resource verifier when the parsed bundled-plugins.json fails structural validation: index.version must equal 1, index.plugins must be an array, and the array must be non-empty. This is a schema check that ensures the plugin index was generated by the correct version of the indexing tool and actually contains at least one plugin.","triggerScenarios":"bundled-plugins.json was parsed successfully but its shape is wrong: the version field is missing or is not 1; the plugins field is missing, is not an array, or is an empty array. This typically indicates the indexing script that generates bundled-plugins.json was changed, is a different version, or produced no plugins.","commonSituations":"The plugin indexing tool was updated and now writes version 2 instead of 1; no plugins were found during indexing so the array is empty; the indexing script has a bug that omits the plugins field; a manual edit corrupted the index structure.","solutions":["Inspect the actual content of bundled-plugins.json: cat <launchRoot>/bundled-plugins.json | python3 -m json.tool.","If version is wrong, update either the indexing tool to write version 1, or update the check in verify-packaged-plugin-resources.cjs:77 to accept the new version.","If the plugins array is empty, investigate why no plugins were indexed — check the plugin build output and the indexing script's discovery logic.","Re-run the plugin indexing/build step to regenerate a valid bundled-plugins.json."],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":null,"typeGuard":"// Validate the bundled plugin index shape before processing.\nfunction isValidPluginIndex(value) {\n  return (\n    typeof value === 'object' &&\n    value !== null &&\n    value.version === 1 &&\n    Array.isArray(value.plugins) &&\n    value.plugins.length > 0\n  )\n}","tryCatchPattern":null,"preventionTips":["Treat the bundled-plugins.json schema (version: 1, plugins: non-empty array) as a versioned contract; update both the producer and consumer together.","Add a JSON Schema file for bundled-plugins.json and validate against it in CI before packaging.","If the indexing tool is updated, run a migration that re-generates all existing indices with the new version."],"tags":["plugin-packaging","ci-gate","resource-verification","schema-validation"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}