{"record":{"id":"dc9d3552169695fe","repo":"CherryHQ/cherry-studio","slug":"internalerror","errorCode":"InternalError","errorMessage":"Product manifest is unavailable","messagePattern":"Product manifest is unavailable","errorType":"error_code","errorClass":"McpError","httpStatus":null,"severity":"error","filePath":"src/main/ai/mcp/servers/assistant.ts","lineNumber":291,"sourceCode":"        }\n      } catch (error) {\n        const message = error instanceof Error ? error.message : String(error)\n        logger.error(`Tool error: ${toolName}`, { error: message })\n        return {\n          content: [{ type: 'text' as const, text: `Error: ${message}` }],\n          isError: true\n        }\n      }\n    })\n  }\n\n  private readProductManifest(): Record<string, unknown> {\n    const manifestPath = application.getPath('feature.agents.assistant.manifest.file')\n    let rawManifest: string\n    try {\n      rawManifest = fs.readFileSync(manifestPath, 'utf-8')\n    } catch {\n      throw new McpError(ErrorCode.InternalError, 'Product manifest is unavailable')\n    }\n\n    let manifest: unknown\n    try {\n      manifest = JSON.parse(rawManifest)\n    } catch {\n      throw new McpError(ErrorCode.InternalError, 'Product manifest contains invalid JSON')\n    }\n    const manifestRecord =\n      typeof manifest === 'object' && manifest !== null && !Array.isArray(manifest)\n        ? (manifest as Record<string, unknown>)\n        : undefined\n    const packageRecord =\n      typeof manifestRecord?.package === 'object' &&\n      manifestRecord.package !== null &&\n      !Array.isArray(manifestRecord.package)\n        ? (manifestRecord.package as Record<string, unknown>)\n        : undefined","sourceCodeStart":273,"sourceCodeEnd":309,"githubUrl":"https://github.com/CherryHQ/cherry-studio/blob/726446b54cd69ffe51a276638672f6d95ca0768c/src/main/ai/mcp/servers/assistant.ts#L273-L309","documentation":"readProductManifest() resolves the manifest path via application.getPath('feature.agents.assistant.manifest.file') and readFileSync's it synchronously. Any error from readFileSync (ENOENT, EACCES, EISDIR, etc.) is caught and re-thrown as McpError InternalError 'Product manifest is unavailable'. This indicates the manifest file is not readable at the configured path.","triggerScenarios":"The manifest file does not exist at the resolved path; the path is a directory; the process lacks read permission; application.getPath returns a wrong/unregistered key. Fires when product_info or navigate tools are invoked.","commonSituations":"The manifest build step did not run or was excluded from packaging; the path namespace key 'feature.agents.assistant.manifest.file' is misconfigured in the paths registry; a dev environment without the generated manifest; the file was deleted post-install.","solutions":["Verify the path resolves correctly: log application.getPath('feature.agents.assistant.manifest.file').","Ensure the manifest generation build step produces the file at that location.","Check read permissions on the file and parent directory."],"exampleFix":"// before: path not registered, returns undefined -> readFileSync(undefined) throws\nconst manifestPath = application.getPath('feature.agents.assistant.manifest.file')\n\n// after: register the path key in the paths namespace, then verify\n// src/main/core/paths/registry must include 'feature.agents.assistant.manifest.file'\nconst manifestPath = application.getPath('feature.agents.assistant.manifest.file')\nconsole.log('manifest at:', manifestPath, fs.existsSync(manifestPath))","handlingStrategy":"validation","validationCode":"import fs from 'node:fs'\nimport { application } from '@application'\n\nconst manifestPath = application.getPath('feature.agents.assistant.manifest.file')\nif (!manifestPath || !fs.existsSync(manifestPath)) {\n  throw new Error(`Manifest path missing or not registered: ${manifestPath}`)\n}","typeGuard":null,"tryCatchPattern":"try {\n  return this.readProductManifest()\n} catch (err) {\n  if (err instanceof McpError && err.code === ErrorCode.InternalError) {\n    logger.error('Manifest unavailable', { path: manifestPath })\n  }\n  throw err\n}","preventionTips":["Register 'feature.agents.assistant.manifest.file' in the paths registry before use.","Ensure the manifest build step runs in CI and packaging.","Add a startup smoke test that reads the manifest so this fails early, not at first tool call."],"tags":["mcp","filesystem","manifest","paths","internal-error","assistant"],"backgroundTag":null,"analyzedSha":"726446b54cd69ffe51a276638672f6d95ca0768c","analyzedAt":"2026-08-12T17:30:37.448Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}