affaan-m/ECC · error
A normalized install request is required
Error message
A normalized install request is required
What it means
createInstallPlanFromRequest only accepts an already-normalized install request object produced by normalizeInstallRequest/request. Passing null, undefined, or a non-object skips planning entirely and throws immediately, since no mode or selections can be read.
Solutions
- Build the request with request()/normalizeInstallRequest() first and pass its result.
- Check the value passed is a non-null object before calling.
- Inspect the call site for a typo or a lost return value from the normalizer.
Example fix
// before createInstallPlanFromRequest(opts) // after const req = normalizeInstallRequest(opts) createInstallPlanFromRequest(req)
Defensive patterns
Strategy: type-guard
Validate before calling
if (request === null || typeof request !== 'object') throw new Error('Call normalizeInstallRequest() first; pass its result to createInstallPlanFromRequest') Type guard
function isNormalizedRequest(x) {
return x !== null && typeof x === 'object' && typeof x.mode === 'string'
}
if (!isNormalizedRequest(req)) throw new TypeError('A normalized install request is required') Try / catch
try {
const plan = createInstallPlanFromRequest(req)
} catch (err) {
if (err.message === 'A normalized install request is required') {
console.error('Request object missing — ensure normalizeInstallRequest() succeeded and its result was passed')
} else throw err
} Prevention
- Always create requests via normalizeInstallRequest/request, never inline literals.
- Check the normalizer's return value before passing it on.
- Don't let an earlier failed async assignment silently leave the request undefined.
- Add a unit test asserting plan creation from a real normalized request.
When it happens
Trigger: Calling createInstallPlanFromRequest(null), createInstallPlanFromRequest(undefined), or passing a primitive such as a string or number instead of the normalized request object.
Common situations: Forgetting to call normalizeInstallRequest before planning; a request variable left undefined because an earlier async call failed silently; refactoring that changed the call signature.
Related errors
- bundle collections must be lists
- Invalid install-state
- Legacy language arguments cannot be combined with…
- local_only must be an exact boolean
- MCP config must be a JSON object
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/6d53148f5e3f02f2.
Report an issue: GitHub.
Appendix: source
Thrown at scripts/lib/install/runtime.js:13
'use strict';
const {
createLegacyCompatInstallPlan,
createLegacyInstallPlan,
createManifestInstallPlan,
} = require('../install-executor');
const { resolveInvocationEnvironment } = require('../invocation-environment');
const { withHookConsent } = require('./hook-consent');
function createInstallPlanFromRequest(request, options = {}) {
if (!request || typeof request !== 'object') {
throw new Error('A normalized install request is required');
}
return withHookConsent(createRawInstallPlan(request, options), request.hookConsent || null);
}
function createRawInstallPlan(request, options = {}) {
if (request.mode === 'manifest') {
return createManifestInstallPlan({
target: request.target,
profileId: request.profileId,
moduleIds: request.moduleIds,
includeComponentIds: request.includeComponentIds,
excludeComponentIds: request.excludeComponentIds,
projectRoot: options.projectRoot,
homeDir: options.homeDir,
env: resolveInvocationEnvironment(options),
sourceRoot: options.sourceRoot,
exemptValidationCodes: options.exemptValidationCodes || [],View on GitHub (pinned to 8321021c54)