upstash/context7 · warning
Skipped ${mcpPath}: could not parse (${err instanceof Error
Error message
Skipped ${mcpPath}: could not parse (${err instanceof Error ? err.message : String(err)}) What it means
Thrown while context7 checks whether the context7 MCP server is registered for an agent (during remove/setup). The resolved agent config path that does not end in .toml is read with readJsonConfig(), which does JSON.parse(stripJsonComments(raw)). If the parse throws, the file is skipped with this warning and hasMcp() returns false, so the agent is treated as 'not configured' instead of the command crashing.
Source
Thrown at packages/cli/src/commands/remove.ts:211
const agent = getAgent(agentName);
// Agents with no project-level MCP (e.g. Antigravity) only have a global
// config — there's nothing to detect at project scope.
if (scope === "project" && agent.mcp.projectPaths.length === 0) return false;
const candidates =
scope === "global"
? agent.mcp.globalPaths
: agent.mcp.projectPaths.map((path) => join(process.cwd(), path));
const mcpPath = await resolveMcpPath(candidates);
if (mcpPath.endsWith(".toml")) {
return readTomlServerExists(mcpPath, "context7");
}
let existing: Record<string, unknown>;
try {
existing = await readJsonConfig(mcpPath);
} catch (err) {
log.warn(
`Skipped ${mcpPath}: could not parse (${err instanceof Error ? err.message : String(err)})`
);
return false;
}
const section = existing[agent.mcp.configKey];
return (
!!section && typeof section === "object" && !Array.isArray(section) && "context7" in section
);
}
async function hasRule(agentName: SetupAgent, scope: Scope): Promise<boolean> {
const agent = getAgent(agentName);
const rule = agent.rule;
if (rule.kind === "file") {
const ruleDir =
scope === "global" ? rule.dir("global") : join(process.cwd(), rule.dir("project"));
return pathExists(join(ruleDir, rule.filename));View on GitHub (pinned to 5284672feb)
Solutions
- Validate the file and fix the reported syntax error: jq . '<configPath>' (or npx jsonlint <configPath>)
- Remove git merge-conflict markers (<<<<<<< / ======= / >>>>>>>) or editor backup blocks from the config
- Restore the config from source control, or regenerate it with the agent's own CLI, then re-run the context7 command
- Keep hand-written configs strict JSON: no comments, no trailing commas
Example fix
// before (.cursor/mcp.json — unparsable)
{
"mcpServers": {
"context7": { "command": "npx", "args": ["-y", "@upstash/context7-mcp"] }, // trailing comma + comment
}
// after
{
"mcpServers": {
"context7": { "command": "npx", "args": ["-y", "@upstash/context7-mcp"] }
}
} Defensive patterns
Strategy: validation
Validate before calling
// before running context7 remove, confirm the agent's config parses
import { readFile } from "node:fs/promises";
const raw = await readFile(configPath, "utf-8");
try {
JSON.parse(raw.replace(/^\uFEFF/, ""));
} catch (e) {
console.error(`Fix ${configPath} first: ${(e as Error).message}`);
} Type guard
function isJsonRecord(v: unknown): v is Record<string, unknown> {
return typeof v === "object" && v !== null && !Array.isArray(v);
} Prevention
- Keep agent MCP configs strict JSON — no comments, no trailing commas
- After hand edits, validate with `jq empty <file>` before running context7 commands
- Resolve git merge conflicts in config files before invoking the CLI
When it happens
Trigger: Running `context7 remove <agent>` (or any flow calling hasMcp) when the agent's JSON MCP config exists but is unparsable: truncated file, trailing commas or single quotes that survive stripJsonComments, merge-conflict markers, or YAML pasted into a .json file. A missing file does NOT trigger this (readJsonConfig returns {} silently); only an existing, syntactically broken file does.
Common situations: Hand-edited ~/.claude.json or .cursor/mcp.json with comments or trailing commas; configs corrupted by an interrupted write or an unresolved git merge; configs emitted by other tools that write non-strict JSON (BOM, unquoted keys).
Related errors
- downloadData.error || "no files"
- await describeErrorResponse(response, fallback)
- err.error_description || err.error || "Device token poll fai
- Failed to write to ${skillPath}: ${error.message}
- No libraries found matching "${library}"
AI-assisted analysis of upstash/context7@5284672feb (2026-08-18).
Data as JSON: /api/errors/eae802c6bab885df.
Report an issue: GitHub.