affaan-m/ECC · error
repoRoot is required to plan Kimi MCP configuration
Error message
repoRoot is required to plan Kimi MCP configuration
What it means
createMcpMergeOperation in the Kimi install target requires a resolved repoRoot to locate the source .mcp.json that will be merged into the Kimi client's MCP configuration. When repoRoot is falsy, the planner cannot build a valid source path, so it throws immediately instead of producing a broken or empty merge plan. This is a fail-fast guard for a missing required planning argument.
Solutions
- Resolve and pass repoRoot explicitly: createMcpMergeOperation(moduleId, process.cwd(), targetRoot) or the detected repository root.
- If calling the higher-level planner, ensure the repoRoot option is included in the planning input object.
- Guard in tests: provide a tmp directory as repoRoot so the .mcp.json existence check runs.
- Check for a recent rename of the option (repoRoot vs repositoryRoot) in the adapter API.
Example fix
// before
const op = createMcpMergeOperation('kimi', null, targetRoot);
// after
const op = createMcpMergeOperation('kimi', path.resolve(repoRoot), targetRoot); Defensive patterns
Strategy: validation
Validate before calling
if (typeof repoRoot !== 'string' || repoRoot.length === 0) {
throw new Error('repoRoot must be resolved before planning Kimi MCP configuration');
} Type guard
const hasRepoRoot = (v) => typeof v === 'string' && v.length > 0;
Prevention
- Always derive repoRoot from process.cwd() or a repo-detection helper at the entry point of installer scripts.
- Validate planning inputs (repoRoot, targetRoot) once at the top of the pipeline before adapter calls.
- In tests, pass a temp directory as repoRoot instead of omitting it.
When it happens
Trigger: Calling createMcpMergeOperation(moduleId, repoRoot, targetRoot) with repoRoot === undefined/null/'' — typically when the adapter's planOperations pipeline is invoked with a planning input whose repoRoot was never resolved or was explicitly set to null in tests.
Common situations: Custom scripts calling the installer planner without passing repoRoot in options; test harnesses stubbing planning inputs; a refactor renaming repoRoot to another option name so the value arrives undefined.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- [ecc-mcp] WARNING
- Install config not found
- MCP config must include an mcpServers object
- mcp_servers. is a legacy name for (run with --update-mcp to…
- mcp_servers. differs from ECC recommendation (run with…
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/999a60e512b5e651.
Report an issue: GitHub.
Appendix: source
Thrown at scripts/lib/install-targets/kimi-project.js:27
function readJsonObject(filePath, label) {
let parsed;
try {
parsed = JSON.parse(fs.readFileSync(filePath, 'utf8'));
} catch (error) {
throw new Error(`Failed to parse ${label} at ${filePath}: ${error.message}`);
}
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
throw new Error(`Invalid ${label} at ${filePath}: expected a JSON object`);
}
return parsed;
}
function createMcpMergeOperation(moduleId, repoRoot, targetRoot) {
if (!repoRoot) {
throw new Error('repoRoot is required to plan Kimi MCP configuration');
}
const sourceRelativePath = '.mcp.json';
const sourcePath = path.join(repoRoot, sourceRelativePath);
if (!fs.existsSync(sourcePath) || !fs.statSync(sourcePath).isFile()) {
return null;
}
return createManagedOperation({
kind: 'merge-json',
moduleId,
sourceRelativePath,
destinationPath: path.join(targetRoot, 'mcp.json'),
strategy: 'merge-json',
scaffoldOnly: false,
mergePayload: readJsonObject(sourcePath, sourceRelativePath),
});
}View on GitHub (pinned to 8321021c54)