CherryHQ/cherry-studio · error · Error
Invalid MCP package env: null byte detected in environment v
Error message
Invalid MCP package env: null byte detected in environment variable name
What it means
Thrown by buildResolvedEnv while iterating environment variables from an MCP package manifest. A key in the env map contained a NUL (\0) byte. Null bytes in env keys are a classic injection vector because they can truncate or confuse downstream C-string handling in the spawned process or the OS exec layer. The guard runs after the env map is received from the manifest but before any value substitution, so it inspects the key as authored.
Source
Thrown at src/main/ai/mcp/McpPackageService.ts:257
const DXT_ENV_DENYLIST = ['NODE_OPTIONS', 'LD_PRELOAD', 'LD_LIBRARY_PATH']
/**
* Validate an MCP package environment map and build a new sanitized object.
* Package env values bypass the command/arg validation, so apply equivalent hardening here:
* reject null bytes in keys/values and denylist process-affecting variables.
*
* @throws Error if a key/value contains a null byte or a key is denylisted
*/
export function buildResolvedEnv(
env: Record<string, string>,
extractDir: string,
userConfig?: Record<string, any>
): Record<string, string> {
const resolvedEnv: Record<string, string> = {}
for (const [key, value] of Object.entries(env)) {
if (key.includes('\0')) {
throw new Error('Invalid MCP package env: null byte detected in environment variable name')
}
// Denylist process-affecting variables (DYLD_* on macOS, plus exact matches above).
const canonicalKey = key.toUpperCase()
if (DXT_ENV_DENYLIST.includes(canonicalKey) || canonicalKey.startsWith('DYLD_')) {
throw new Error(`Invalid MCP package env: environment variable "${key}" is not allowed`)
}
const substituted = performVariableSubstitution(value, extractDir, userConfig)
if (substituted.includes('\0')) {
throw new Error(`Invalid MCP package env: null byte detected in value of environment variable "${key}"`)
}
resolvedEnv[key] = substituted
}
return resolvedEnv
}View on GitHub (pinned to 726446b54c)
Solutions
- Open the package's manifest.json and scan server.mcp_config.env keys (and platform_overrides.env keys) for embedded NUL or other control characters; remove them.
- If the manifest was generated, fix the generator to strip control characters from env keys before writing JSON.
- Repackage and re-upload; the install is atomic so no partial state remains.
Defensive patterns
Strategy: validation
Validate before calling
function hasCleanEnvKeys(env: Record<string, string>): boolean {
return Object.keys(env).every((k) => !k.includes('\0'))
} Type guard
function isCleanEnvKey(key: string): boolean {
return typeof key === 'string' && !key.includes('\0')
} Prevention
- Lint manifest.json files for control characters in keys as part of the package build pipeline.
- Treat any env key containing \0 as a corrupt or hostile package and reject before install.
- When generating manifests programmatically, construct keys from a known-safe character set.
When it happens
Trigger: A manifest's server.mcp_config.env (or a platform_overrides env map merged in by applyPlatformOverrides) has a key containing a literal \0, e.g. "FOO\0BAR". JSON permits escaped control characters, so this can survive parsing intact.
Common situations: A hand-edited manifest with a copy-paste error introduced a control character; a malicious or corrupted package was uploaded; a build tool that generated the manifest emitted raw bytes instead of UTF-8 text.
Related errors
- Invalid MCP package env: null byte detected in value of envi
- Invalid MCP package env: environment variable "${key}" is no
- Invalid command: null byte detected
- Invalid args: null byte detected in argument at index ${inde
- Invalid args: path traversal detected in argument at index $
AI-assisted analysis of CherryHQ/cherry-studio@726446b54c (2026-08-12).
Data as JSON: /api/errors/0eca2570a9207990.
Report an issue: GitHub.