nexu-io/open-design · error · Error
resume must be a boolean
Error message
resume must be a boolean
What it means
Thrown by the MCP run-start helper in apps/daemon/src/mcp.ts while assembling the body for POST /api/runs. When the caller supplies a `resume` field it must already be a JS boolean; the MCP layer refuses to coerce strings/numbers because `resume:true` has billing and idempotency side effects (resuming a paused Cloud run via requestId). The guard runs before the request is sent, so no daemon round trip occurs.
Source
Thrown at apps/daemon/src/mcp.ts:2519
options.analyticsHeaders?.[ANALYTICS_HEADER_HOST_PRODUCT] ?? 'unknown',
externalPluginId: options.pluginAttribution.context.id,
externalPluginVersion:
options.pluginAttribution.context.version,
distributionMechanism:
options.pluginAttribution.context.distributionMechanism,
publisherClass: options.pluginAttribution.context.publisherClass,
// This payload is client-supplied. The daemon validates it against the
// request identity/digest and upgrades to session_correlated only after
// the Run/workflow binding is accepted.
attributionQuality: 'self_reported',
pluginWorkflowId: options.pluginAttribution.pluginWorkflowId,
logicalRequestDigest: logical.digest,
logicalRequestDigestVersion: logical.version,
briefState: options.briefState ?? 'not_applicable',
};
}
if (args.resume !== undefined) {
if (typeof args.resume !== 'boolean') throw new Error('resume must be a boolean');
body.resume = args.resume;
}
if (typeof args.prompt === 'string' && args.prompt.length > 0) {
body.message = args.prompt;
body.currentPrompt = args.prompt;
}
if (typeof args.skill === 'string' && args.skill.length > 0) body.skillId = args.skill;
if (Array.isArray(args.skills) && args.skills.length > 0) body.skillIds = args.skills;
if (typeof args.plugin === 'string' && args.plugin.length > 0) body.pluginId = args.plugin;
if (typeof args.agent === 'string' && args.agent.length > 0) body.agentId = args.agent;
if (typeof args.model === 'string' && args.model.length > 0) body.model = args.model;
if (typeof args.serviceTier === 'string' && args.serviceTier.length > 0) {
body.serviceTier = args.serviceTier;
}
if (args.inputs !== undefined) {
if (args.inputs === null || typeof args.inputs !== 'object' || Array.isArray(args.inputs)) {
throw new Error('inputs must be an object');
}View on GitHub (pinned to 5be4028344)
Solutions
- Pass `resume` as a literal boolean: `resume: true` (or `false`), never quoted.
- If the value comes from untyped JSON, coerce before the call: `resume: Boolean(value)` only when you actually intend to resume.
- Omit `resume` entirely when you are not resuming a paused Cloud run — the field is optional.
- Re-check that requestId is the exact original logical-run id when resuming; resume without it starts a fresh run.
Example fix
// before
{ requestId: id, resume: "true" }
// after
{ requestId: id, resume: true } Defensive patterns
Strategy: type-guard
Validate before calling
const resume = args.resume;
if (resume !== undefined && typeof resume !== 'boolean') {
throw new TypeError('resume must be boolean, got ' + typeof resume);
} Type guard
function isResume(v: unknown): v is boolean | undefined {
return v === undefined || typeof v === 'boolean';
} Prevention
- Declare resume as `boolean` (not string) in your MCP tool's JSON schema.
- Coerce untyped config with `Boolean()` only when resuming is intended.
- Omit resume for fresh runs rather than passing false explicitly to avoid confusion.
When it happens
Trigger: Calling the start_run MCP tool with `resume: "true"`, `resume: 1`, or `resume: "yes"` instead of the literal boolean `true`. Also happens when a client JSON-parses config into a string field, or when an agent emits resume as an enum string.
Common situations: Agent/LLM tool-call arguments arrive as strings from JSON schemas that declare resume as string; shell-driven MCP clients passing `--resume true`; copying a requestId-based retry payload from docs that quote the boolean.
Related errors
- inputs must be an object
- artifactManifest must be an object
- existing config at ${where} is not valid JSON: ${err instanc
- existing config at ${where} is not a JSON object
- pluginWorkflowId requires a validated externalPluginContext
AI-assisted analysis of nexu-io/open-design@5be4028344 (2026-08-12).
Data as JSON: /api/errors/e1c5edf21d8d9428.
Report an issue: GitHub.