affaan-m/ECC · critical · Error
Unsupported install target scope: ${scope}
Error message
Unsupported install target scope: ${scope} What it means
Thrown by resolveBaseRoot(scope, input) in scripts/lib/install-targets/helpers.js. The function translates an adapter's configured kind into a base directory on disk; only 'home' (returns input.homeDir || os.homedir()) and 'project' (returns input.projectRoot || input.repoRoot, throwing if both are absent) are supported. Any other scope is an internal invariant violation: createInstallTargetAdapter only constructs adapters whose kind is one of these two, so the throw indicates a custom adapter registered with a novel kind or a caller invoking resolveBaseRoot directly with an unsupported value.
Source
Thrown at scripts/lib/install-targets/helpers.js:53
}
return false;
}
function resolveBaseRoot(scope, input = {}) {
if (scope === 'home') {
return input.homeDir || os.homedir();
}
if (scope === 'project') {
const projectRoot = input.projectRoot || input.repoRoot;
if (!projectRoot) {
throw new Error('projectRoot or repoRoot is required for project install targets');
}
return projectRoot;
}
throw new Error(`Unsupported install target scope: ${scope}`);
}
function buildValidationIssue(severity, code, message, extra = {}) {
return {
severity,
code,
message,
...extra,
};
}
function listRelativeFiles(dirPath, prefix = '') {
if (!fs.existsSync(dirPath)) {
return [];
}
const entries = fs.readdirSync(dirPath, { withFileTypes: true }).sort((left, right) => (
left.name.localeCompare(right.name)View on GitHub (pinned to 01e15490f0)
Solutions
- Confirm the adapter's kind is exactly the string 'home' or 'project' — those are the only two scopes resolveBaseRoot branches on.
- If a genuinely new scope is required, add a branch in scripts/lib/install-targets/helpers.js that returns a concrete absolute path, and document it.
- Stop calling resolveBaseRoot directly; use adapter.resolveRoot(input), which forwards the adapter's configured kind.
- Audit the call site that produced the scope value — it almost certainly came from a hand-built adapter config object rather than createInstallTargetAdapter.
Example fix
// before
const adapter = createInstallTargetAdapter({
id: 'foo', target: 'foo', kind: 'workspace',
rootSegments: ['.foo'], installStatePathSegments: ['state.json'],
});
adapter.resolveRoot({}); // throws: Unsupported install target scope: workspace
// after
const adapter = createInstallTargetAdapter({
id: 'foo', target: 'foo', kind: 'project',
rootSegments: ['.foo'], installStatePathSegments: ['state.json'],
});
adapter.resolveRoot({ projectRoot: '/abs/path' }); Defensive patterns
Strategy: validation
Validate before calling
const SUPPORTED_SCOPES = new Set(['home', 'project']);
function isValidAdapterKind(kind) {
return SUPPORTED_SCOPES.has(kind);
}
// before registering or invoking:
if (!isValidAdapterKind(adapterConfig.kind)) {
throw new TypeError(`Adapter kind '${adapterConfig.kind}' is unsupported; use 'home' or 'project'.`);
} Type guard
function isAdapterKind(value) {
return value === 'home' || value === 'project';
} Prevention
- Only use createInstallTargetAdapter from helpers.js to build adapters; never hand-roll the kind field.
- When forking ECC, decide upfront whether a new target lives under the user home (kind 'home') or a project root (kind 'project').
- Treat resolveBaseRoot as internal — never call it directly from outside helpers.js.
When it happens
Trigger: Registering a custom adapter via createInstallTargetAdapter({ kind: 'workspace', ... }) and calling adapter.resolveRoot({}); calling resolveBaseRoot('user', {}) directly from outside helpers.js; a fork that adds a third scope without extending resolveBaseRoot.
Common situations: Forking ECC to add a new install surface and reusing 'kind' for a value that is neither 'home' nor 'project'; passing a typo'd kind string when constructing an adapter; version drift where a newer adapter definition emits a kind this older helpers.js does not recognize.
Related errors
- Unknown install target adapter: ${targetOrAdapterId}
- Failed to parse ${label} at ${filePath}: ${error.message}
- Invalid ${label} at ${filePath}: expected a JSON object
- repoRoot is required to plan Kimi MCP configuration
- Refusing to apply install operation: missing destination pat
AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13).
Data as JSON: /api/errors/9d08751fb32698c0.
Report an issue: GitHub.