nexu-io/open-design · warning · Error
artifactType must be one of: ${Object.keys(openDesignBriefCa
Error message
artifactType must be one of: ${Object.keys(openDesignBriefCatalog).join(', ')} What it means
readArtifactType rejects any value that is not a string key of openDesignBriefCatalog (packages/contracts/src/api/brief.ts), which defines exactly eight artifact types such as website and product-prototype. The thrown message enumerates the accepted keys at runtime, so the canonical list is whatever the current catalog exposes.
Source
Thrown at apps/daemon/src/mcp-brief.ts:510
? { externalPluginContext: draft.externalPluginContext }
: {}),
};
draft.confirmation = confirmation;
draft.confirmationAnswersDigest = confirmationAnswersDigest;
if (draft.pluginWorkflowId && draft.briefState !== 'skipped') {
draft.briefState = 'confirmed';
}
return confirmation;
},
};
}
function readArtifactType(value: unknown): OpenDesignBriefArtifactType {
if (
typeof value !== 'string'
|| !Object.hasOwn(openDesignBriefCatalog, value)
) {
throw new Error(
`artifactType must be one of: ${Object.keys(openDesignBriefCatalog).join(', ')}`,
);
}
return value as OpenDesignBriefArtifactType;
}
export function readBriefLocale(value: unknown): LocalMcpBriefLocale {
if (typeof value !== 'string' || value.trim().length === 0) return 'en';
const normalized = value.trim().replaceAll('_', '-').toLowerCase();
if (normalized === 'zh' || normalized === 'zh-cn' || normalized.startsWith('zh-hans')) {
return 'zh-CN';
}
if (
normalized === 'zh-tw'
|| normalized === 'zh-hk'
|| normalized === 'zh-mo'
|| normalized.startsWith('zh-hant')
) {View on GitHub (pinned to 5be4028344)
Solutions
- Pass one of the keys printed in the error message.
- Source the allowed set from OPEN_DESIGN_BRIEF_ARTIFACT_TYPES in @open-design/contracts instead of hardcoding.
- Align the contracts dependency version with the daemon.
Example fix
// before
collect_brief({ artifactType: 'web-site' }) // typo -> throws [364]
// after
collect_brief({ artifactType: 'website' }) Defensive patterns
Strategy: type-guard
Validate before calling
import { OPEN_DESIGN_BRIEF_ARTIFACT_TYPES } from '@open-design/contracts';
const valid = new Set(OPEN_DESIGN_BRIEF_ARTIFACT_TYPES);
if (!valid.has(artifactType)) {
throw new Error(`artifactType must be one of: ${[...valid].join(', ')}`);
} Type guard
import { OPEN_DESIGN_BRIEF_ARTIFACT_TYPES } from '@open-design/contracts';
function isArtifactType(v: unknown): v is OpenDesignBriefArtifactType {
return typeof v === 'string' && OPEN_DESIGN_BRIEF_ARTIFACT_TYPES.includes(v as any);
} Prevention
- Never hardcode the artifactType list; import it from @open-design/contracts.
- Validate before calling collect_brief.
- Keep the contracts dependency version aligned with the daemon.
When it happens
Trigger: Passing artifactType as undefined, a number, an empty string, a typo, or a value from an older or newer version whose catalog keys differ.
Common situations: Version skew between the contracts package the caller hardcoded and the daemon's catalog; free-text artifactType supplied by an LLM.
Related errors
- pluginWorkflowId requires a validated externalPluginContext
- The Open Design brief is incomplete. Missing: ${missing.join
- projectTitle must be at most 256 characters
- ${field} must be a non-empty string
- ${field} must be an object
AI-assisted analysis of nexu-io/open-design@5be4028344 (2026-08-12).
Data as JSON: /api/errors/743be0530131c3e7.
Report an issue: GitHub.