nanocoai/nanoclaw · error · Error
args must be a JSON array of strings
Error message
args must be a JSON array of strings
What it means
The `args` field of a stdio MCP entry is not an array of strings (or is not an array at all — args defaults to [] only when undefined). Non-string args would be passed to a child process spawn and fail confusingly later, so the shape is validated here.
Source
Thrown at src/container-config.ts:182
for (const key of parsed.searchParams.keys()) {
if (SECRET_QUERY_KEY_RE.test(key.replace(CAMEL_SPLIT_RE, '$1_$2'))) {
throw new Error(`url query parameter "${key}" looks like a credential; use OneCLI for authentication`);
}
}
const headers = parseStringRecord(input.headers, 'headers');
return {
type: 'http',
url,
...(headers === undefined ? {} : { headers }),
...(instructions === undefined ? {} : { instructions }),
};
}
if (command === undefined) throw new Error('Provide exactly one of command or url');
if (input.headers !== undefined) throw new Error('headers is only valid with url');
const args = input.args ?? [];
if (!Array.isArray(args) || !args.every((arg) => typeof arg === 'string')) {
throw new Error('args must be a JSON array of strings');
}
const env = parseStringRecord(input.env, 'env') ?? {};
for (const key of Object.keys(env)) {
if (!ENV_KEY_RE.test(key)) {
throw new Error(`env key ${JSON.stringify(key)} must be a valid environment variable name`);
}
}
const cwd = parseCwd(input.cwd);
return {
command,
args,
env,
...(cwd === undefined ? {} : { cwd }),
...(instructions === undefined ? {} : { instructions }),
};
}
function parseStringRecord(value: unknown, flag: string): Record<string, string> | undefined {View on GitHub (pinned to 294ef2aee8)
Solutions
- Make args a JSON array of strings: ["-y","server"]
- Quote every element; numbers must be stringified
- Validate the whole entry JSON before saving
Example fix
// before
{"command":"npx","args":"-y server"}
// after
{"command":"npx","args":["-y","server"]} Defensive patterns
Strategy: validation
Validate before calling
if (entry.args !== undefined && (!Array.isArray(entry.args) || !entry.args.every(a => typeof a === 'string'))) entry.args = entry.args.map(String);
Type guard
function isValidArgs(a: unknown): a is string[] { return Array.isArray(a) && a.every(x => typeof x === 'string'); } Try / catch
catch (err) { if (err.message.includes('args must be a JSON array')) coerceArgsToArray(); else throw err; } Prevention
- Never pass shell-style single-string args
- Stringify all numeric args at authoring time
When it happens
Trigger: args: "-y server" (string instead of array), args: ["-y", 42], or args: {"0":"-y"} in a stdio entry.
Common situations: Writing shell-style single-string args; numbers creeping in from JSON templating; a single arg passed unquoted.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- MCP instructions must be a string
- ${flag} must be a JSON object with string values
- type "stdio" requires command
- type "http" requires url
- Provide exactly one of command or url
AI-assisted analysis of nanocoai/nanoclaw@294ef2aee8 (2026-08-28).
Data as JSON: /api/errors/18da3d93b88d4d5c.
Report an issue: GitHub.