{"record":{"id":"47f805386ab8f160","repo":"nanocoai/nanoclaw","slug":"container-config-not-found-for-agent-group-agen","errorCode":null,"errorMessage":"Container config not found for agent group: ${agentGroupId}","messagePattern":"Container config not found for agent group: (.+?)","errorType":"error_code","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"src/container-config.ts","lineNumber":388,"sourceCode":"    maxMessagesPerPrompt: row.max_messages_per_prompt ?? undefined,\n    model: row.model ?? undefined,\n    effort: row.effort ?? undefined,\n    timezone: row.timezone && isValidTimezone(row.timezone) ? row.timezone : undefined,\n    runtimeTier: parseRuntimeTier(row.runtime_tier, group.name),\n  };\n}\n\n/**\n * Materialize `container.json` from the DB. Called at spawn time so the\n * container always sees fresh config. Returns the `ContainerConfig` for\n * use by the caller (buildMounts, composeSessionSpec, etc.).\n */\nexport async function materializeContainerJson(agentGroupId: string): Promise<ContainerConfig> {\n  const group = await getAgentGroup(agentGroupId);\n  if (!group) throw new Error(`Agent group not found: ${agentGroupId}`);\n\n  const row = await getContainerConfig(agentGroupId);\n  if (!row) throw new Error(`Container config not found for agent group: ${agentGroupId}`);\n\n  const config = configFromDb(row, group);\n\n  const p = path.join(GROUPS_DIR, group.folder, 'container.json');\n  const dir = path.dirname(p);\n  if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });\n  fs.writeFileSync(p, JSON.stringify(config, null, 2) + '\\n');\n\n  return config;\n}\n","sourceCodeStart":370,"sourceCodeEnd":399,"githubUrl":"https://github.com/nanocoai/nanoclaw/blob/294ef2aee85218b23ad30eda9dfe10e590b54a8c/src/container-config.ts#L370-L399","documentation":"materializeContainerJson found the agent group but no row in container_configs for it. Normally backfill-container-configs.ts creates a default row at startup, so a missing row means the backfill was skipped, the row was deleted, or the group was created outside the normal path.","triggerScenarios":"Group created by direct DB insert without a container_configs row; container_configs row deleted manually; startup backfill (backfill-container-configs.ts) failed or hasn't run yet after adding a group.","commonSituations":"Manual DB seeding during migration testing; an old install upgraded without running migrations; deleting the config row to 'reset' it.","solutions":["Restart the host (pnpm run dev / systemctl --user restart nanoclaw) so backfill creates the default row","Or insert one programmatically via the createContainerConfig path / ncl groups config update","If migrations were skipped, run them, then restart","Check logs/nanoclaw.error.log for a failed backfill"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"let row = await getContainerConfig(agentGroupId); if (!row) { row = await createDefaultContainerConfig(agentGroupId); } // or trigger backfill","typeGuard":null,"tryCatchPattern":"try { await materializeContainerJson(id); } catch (err) { if (err.message.includes('Container config not found')) { await runBackfill(); return await materializeContainerJson(id); } throw err; }","preventionTips":["Create groups through the supported paths (ncl groups create / init-first-agent) so container_configs rows are seeded","Restart the host after manual DB repairs so backfill runs","Keep migrations current; check logs/nanoclaw.error.log for backfill failures"],"tags":["container-config","db-integrity","spawn"],"backgroundTag":"missing-config-row","analyzedSha":"294ef2aee85218b23ad30eda9dfe10e590b54a8c","analyzedAt":"2026-08-28T13:59:10.357Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}