nanocoai/nanoclaw · warning
Stored skill selection is not "all" or a string list; inlini
Error message
Stored skill selection is not "all" or a string list; inlining every skill
What it means
The `skills` column for an agent group was expected to be the JSON string `"all"` or a JSON array of skill-name strings, but the stored value parses to something else (or fails to parse). The parser falls back to `'all'`, inlining every skill into the container.
Source
Thrown at src/container-config.ts:351
* match and silently drop skills.
*
* The single reading of this column. `configFromDb` used to cast it instead,
* which threw on a corrupt row before the composer's tolerance could apply:
* every spawn failed, and `wakeContainer`'s retry contract darkened the group.
* Two readings that must agree is also how the document ends up teaching a
* skill the agent was never given.
*/
export function parseSkillSelection(raw: string | undefined, groupName: string): string[] | 'all' {
if (raw === undefined) return 'all';
let parsed: unknown;
try {
parsed = JSON.parse(raw);
} catch {
parsed = undefined;
}
if (parsed === 'all') return 'all';
if (Array.isArray(parsed) && parsed.every((n) => typeof n === 'string')) return parsed;
log.warn('Stored skill selection is not "all" or a string list; inlining every skill', { group: groupName });
return 'all';
}
/** Build a `ContainerConfig` from a DB row + agent group identity. */
export function configFromDb(row: ContainerConfigRow, group: AgentGroup): ContainerConfig {
return {
mcpServers: sanitizeStoredMcpServers(JSON.parse(row.mcp_servers), group.name),
packages: {
apt: JSON.parse(row.packages_apt) as string[],
npm: JSON.parse(row.packages_npm) as string[],
},
imageTag: row.image_tag ?? undefined,
additionalMounts: JSON.parse(row.additional_mounts) as AdditionalMountConfig[],
skills: parseSkillSelection(row.skills, group.name),
provider: row.provider ?? undefined,
groupName: group.name,
assistantName: row.assistant_name ?? group.name,
agentGroupId: group.id,View on GitHub (pinned to 294ef2aee8)
Solutions
- Fix the stored value: `ncl groups config update --skills all` or a proper JSON array string `'["skill-a"]'`
- Inspect the row: `pnpm exec tsx scripts/q.ts data/v2.db "select skills from container_configs"`
- Verify which skills get inlined after the fix
Example fix
// before (stored): skills = main // after (stored): skills = "[\"main\"]"
Defensive patterns
Strategy: validation
Validate before calling
function isValidSkills(raw: string): boolean {
try {
const p = JSON.parse(raw);
return p === 'all' || (Array.isArray(p) && p.every((n) => typeof n === 'string'));
} catch { return false; }
} Type guard
function isSkillSelection(v: unknown): v is 'all' | string[] {
return v === 'all' || (Array.isArray(v) && v.every((n) => typeof n === 'string'));
} Prevention
- Only set skills via `ncl groups config update --skills ...`
- Store arrays as JSON strings: '["name"]'
- Never write bare comma-separated names into the column
When it happens
Trigger: `configFromDb`/`selectedSkills`/`parseSkillSelection` reading a `skills` value like `["a", 1]`, `"main"`, `true`, or malformed JSON such as `['a','b']`.
Common situations: Manually editing the container_configs.skills column with non-JSON syntax; an older write path storing a bare string; a CLI flag writing unquoted values.
Related errors
- No container config for group: ${id}
- --cli-scope must be one of: disabled, group, global
- Nothing to update — provide at least one of: --provider, --m
- server name must be 1-64 characters of letters, digits, "_"
- unsupported transport "sse"
AI-assisted analysis of nanocoai/nanoclaw@294ef2aee8 (2026-08-28).
Data as JSON: /api/errors/2a38f2eb3f977ae7.
Report an issue: GitHub.