CherryHQ/cherry-studio · error · McpError

InternalError

InternalError

Error message

Product manifest is unavailable

What it means

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.

Source

Thrown at src/main/ai/mcp/servers/assistant.ts:291

        }
      } catch (error) {
        const message = error instanceof Error ? error.message : String(error)
        logger.error(`Tool error: ${toolName}`, { error: message })
        return {
          content: [{ type: 'text' as const, text: `Error: ${message}` }],
          isError: true
        }
      }
    })
  }

  private readProductManifest(): Record<string, unknown> {
    const manifestPath = application.getPath('feature.agents.assistant.manifest.file')
    let rawManifest: string
    try {
      rawManifest = fs.readFileSync(manifestPath, 'utf-8')
    } catch {
      throw new McpError(ErrorCode.InternalError, 'Product manifest is unavailable')
    }

    let manifest: unknown
    try {
      manifest = JSON.parse(rawManifest)
    } catch {
      throw new McpError(ErrorCode.InternalError, 'Product manifest contains invalid JSON')
    }
    const manifestRecord =
      typeof manifest === 'object' && manifest !== null && !Array.isArray(manifest)
        ? (manifest as Record<string, unknown>)
        : undefined
    const packageRecord =
      typeof manifestRecord?.package === 'object' &&
      manifestRecord.package !== null &&
      !Array.isArray(manifestRecord.package)
        ? (manifestRecord.package as Record<string, unknown>)
        : undefined

View on GitHub (pinned to 726446b54c)

Solutions

  1. Verify the path resolves correctly: log application.getPath('feature.agents.assistant.manifest.file').
  2. Ensure the manifest generation build step produces the file at that location.
  3. Check read permissions on the file and parent directory.

Example fix

// before: path not registered, returns undefined -> readFileSync(undefined) throws
const manifestPath = application.getPath('feature.agents.assistant.manifest.file')

// after: register the path key in the paths namespace, then verify
// src/main/core/paths/registry must include 'feature.agents.assistant.manifest.file'
const manifestPath = application.getPath('feature.agents.assistant.manifest.file')
console.log('manifest at:', manifestPath, fs.existsSync(manifestPath))
Defensive patterns

Strategy: validation

Validate before calling

import fs from 'node:fs'
import { application } from '@application'

const manifestPath = application.getPath('feature.agents.assistant.manifest.file')
if (!manifestPath || !fs.existsSync(manifestPath)) {
  throw new Error(`Manifest path missing or not registered: ${manifestPath}`)
}

Try / catch

try {
  return this.readProductManifest()
} catch (err) {
  if (err instanceof McpError && err.code === ErrorCode.InternalError) {
    logger.error('Manifest unavailable', { path: manifestPath })
  }
  throw err
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of CherryHQ/cherry-studio@726446b54c (2026-08-12). Data as JSON: /api/errors/dc9d3552169695fe. Report an issue: GitHub.