{"record":{"id":"a6afb63ebe057b14","repo":"tinyhumansai/openhuman","slug":"integrations-agent-must-use-promptsource-dynamic","errorCode":null,"errorMessage":"integrations_agent must use PromptSource::Dynamic; got {:?}","messagePattern":"integrations_agent must use PromptSource::Dynamic; got (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src/openhuman/agent/debug/mod.rs","lineNumber":405,"sourceCode":"            parameters_schema: Some(t.parameters_schema().to_string()),\n        })\n        .collect();\n\n    // Narrow the connected_integrations slice to just the bound\n    // toolkit so the prompt's Connected Integrations / tool catalogue\n    // doesn't leak peer toolkits into this sub-agent's context.\n    let narrow_integrations = vec![integration.clone()];\n\n    let registry = AgentDefinitionRegistry::global()\n        .ok_or_else(|| anyhow!(\"AgentDefinitionRegistry missing after init\"))?;\n    let definition: AgentDefinition = registry\n        .get(INTEGRATIONS_AGENT_ID)\n        .cloned()\n        .ok_or_else(|| anyhow!(\"integrations_agent definition not in registry\"))?;\n    let build = match &definition.system_prompt {\n        PromptSource::Dynamic(f) => *f,\n        _ => {\n            return Err(anyhow!(\n                \"integrations_agent must use PromptSource::Dynamic; got {:?}\",\n                match &definition.system_prompt {\n                    PromptSource::Inline(_) => \"Inline\",\n                    PromptSource::File { .. } => \"File\",\n                    PromptSource::Dynamic(_) => \"Dynamic\",\n                }\n            ));\n        }\n    };\n\n    let empty_visible: HashSet<String> = HashSet::new();\n    let model_name = definition.model.resolve(agent.model_name()).to_string();\n    let ctx = PromptContext {\n        workspace_dir: agent.workspace_dir(),\n        model_name: &model_name,\n        agent_id: INTEGRATIONS_AGENT_ID,\n        tools: &prompt_tools,\n        workflows: agent.workflows(),","sourceCodeStart":387,"sourceCodeEnd":423,"githubUrl":"https://github.com/tinyhumansai/openhuman/blob/a221052e0df5b1f7598fceba7329fd1af95d6699/src/openhuman/agent/debug/mod.rs#L387-L423","documentation":"The integrations_agent's system prompt must be PromptSource::Dynamic — the whole agent exists as a parameterized per-toolkit prompt factory. At src/openhuman/agent/debug/mod.rs:405 the loaded definition's system_prompt is Inline or File (the match stringifies which), so the renderer cannot obtain a build function and errors. The bundled builtin is always Dynamic (loader injects PromptSource::Dynamic at parse_builtin), so a static prompt means a workspace override rewrote it.","triggerScenarios":"A workspace agents TOML override for integrations_agent sets `system_prompt = \"...\"` (Inline) or `system_prompt = { file = \"...\" }` (File); hand-crafted override files copied from another agent's shape.","commonSituations":"Users customizing the integrations_agent prompt statically, not realizing its per-toolkit expansion requires the dynamic builder; downgrading/upgrade migration writing static prompts; copy-paste of an agent TOML template with an inline prompt.","solutions":["Remove the static system_prompt from the integrations_agent override so the builtin Dynamic source is used.","If you must customize it, keep a dynamic prompt source that closes over the toolkit context instead of static text.","Verify by re-dumping: integrations_agent should expand per connected toolkit."],"exampleFix":"# before: <workspace>/agents/integrations_agent.toml\n[definition]\nsystem_prompt = \"You handle integrations.\"   # -> Inline, errors\n# after: delete the override (or keep dynamic)\nrm <workspace>/agents/integrations_agent.toml","handlingStrategy":"validation","validationCode":"use crate::openhuman::agent::harness::definition::PromptSource;\n\nmatch &definition.system_prompt {\n    PromptSource::Dynamic(_) => { /* safe to render */ }\n    other => anyhow::bail!(\"integrations_agent prompt source must stay Dynamic; got {other:?}\"),\n}","typeGuard":"fn is_dynamic_prompt(\n    def: &crate::openhuman::agent::harness::definition::AgentDefinition,\n) -> bool {\n    matches!(def.system_prompt, PromptSource::Dynamic(_))\n}","tryCatchPattern":"match &definition.system_prompt {\n    PromptSource::Dynamic(build) => (*build)(ctx).await,\n    _ => {\n        // A workspace override replaced the dynamic factory with static text.\n        // Refuse (this error) rather than rendering a toolkit-blind prompt.\n    }\n}","preventionTips":["Do not set static system_prompt overrides for agents whose builtin prompt is dynamic.","When customizing dynamic agents, keep a dynamic builder that closes over toolkit context.","After editing overrides, dump the agent's prompt to verify it still expands per toolkit."],"tags":["rust","agent-definitions","prompt-source","workspace-overrides","integrations","debug"],"backgroundTag":null,"analyzedSha":"a221052e0df5b1f7598fceba7329fd1af95d6699","analyzedAt":"2026-08-16T12:47:06.542Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}