nexu-io/open-design · error · Error
artifactManifest must be an object
Error message
artifactManifest must be an object
What it means
Thrown in the artifact-creation MCP handler before POSTing to the artifact endpoint. `artifactManifest` is an optional structured manifest describing the artifact; if present it must be a plain object so downstream artifact rendering can read named fields. null, arrays, and primitives are rejected to fail fast rather than produce a malformed artifact.
Source
Thrown at apps/daemon/src/mcp.ts:2854
return null;
}
}
async function createArtifact(
baseUrl: string,
args: McpArgs,
headers?: Record<string, string>,
) {
const { id, resolved, active } = await resolveProjectArg(baseUrl, args.project, headers);
requireString(args.name, 'name');
requireString(args.content, 'content');
if (
args.artifactManifest !== undefined &&
(args.artifactManifest === null ||
typeof args.artifactManifest !== 'object' ||
Array.isArray(args.artifactManifest))
) {
throw new Error('artifactManifest must be an object');
}
const artifactManifest =
args.artifactManifest
? args.artifactManifest
: undefined;
const payload = await postCreateArtifactRequest({
baseUrl,
projectId: id,
...(headers ? { headers } : {}),
input: {
name: args.name,
content: args.content,
encoding: args.encoding === 'base64' ? 'base64' : 'utf8',
...(artifactManifest === undefined ? {} : { artifactManifest }),
},
});
const result = payload && typeof payload === 'object' && !Array.isArray(payload)
? (payload as JsonObject)View on GitHub (pinned to 5be4028344)
Solutions
- Pass a plain object: `artifactManifest: { ... }`, or omit it to use the default.
- Parse serialized manifests: `artifactManifest: JSON.parse(raw)`.
- If you built an array of manifests, pick the single intended entry.
- Verify the manifest field names against the artifact route's expected schema in packages/contracts.
Example fix
// before
{ name, content, artifactManifest: null }
// after
{ name, content } // omit when default manifest is fine Defensive patterns
Strategy: type-guard
Validate before calling
if (artifactManifest !== undefined && (artifactManifest === null || typeof artifactManifest !== 'object' || Array.isArray(artifactManifest))) {
throw new TypeError('artifactManifest must be a plain object');
} Type guard
function isManifest(v: unknown): v is Record<string, unknown> {
return typeof v === 'object' && v !== null && !Array.isArray(v);
} Prevention
- Omit artifactManifest when the default is acceptable.
- Parse serialized manifests before submission.
- Validate the manifest against the artifact route's contract schema.
When it happens
Trigger: Calling the create-artifact MCP tool with `artifactManifest: [...]`, `artifactManifest: null`, or a JSON string. Happens when a caller copies a list of manifest entries into the field, or forwards a serialized manifest without parsing.
Common situations: LLM emits an array because the schema is ambiguous; manifest imported from a JSON file left as a string; passing the whole request envelope instead of its manifest sub-object.
Related errors
- resume must be a boolean
- inputs must be an object
- invalid JSON in ${filePath}: ${message}
- ${filePath} must contain a JSON object
- ARTIFACT_MANIFEST_INVALID
AI-assisted analysis of nexu-io/open-design@5be4028344 (2026-08-12).
Data as JSON: /api/errors/99e3e2ac11c77ec9.
Report an issue: GitHub.