Error Handling
Errors fall into two groups: things Kit rejects the moment you call the method, and things only the platform can check, because they depend on your whole project, not just one object.
Kit-level errors
These throw immediately in your own code, with no CLI involved. Duplicate step IDs or names: workflow step IDs and names must be unique within a workflow:
workflow.addStep(new Step({ name: 'Prepare', type: 'core.set' }));
// This will throw an error:
workflow.addStep(new Step({ name: 'Prepare', type: 'core.set' }));
Missing connections. If you connect two steps, both must be explicitly added to the workflow's steps array:
const first = new Step({ name: 'First', type: 'manualTrigger' });
const second = new Step({ name: 'Second', type: 'core.set' });
first.connectTo(second);
// This will throw when converted to a runtime workflow
const workflow = new Workflow({
id: 'broken-workflow',
name: 'Broken',
steps: [first], // 'second' is missing!
});
Validated on sync and deploy
culvii dev and culvii deploy run the same validators, in the same order. Nothing is deploy-only: whatever would fail a deploy already failed your last dev sync, just earlier.
Invalid model configuration. An agent's model must be an object carrying a provider, a modelId, and a credentialId:
// Good
model: { provider: 'openai', modelId: 'gpt-4o', credentialId: 'my-openai-credential' }
// Bad: rejected, model must include a credentialId
model: 'openai/gpt-4o'
There's no env-var fallback, so a legacy '<provider>/<model-id>' string is rejected. Supported providers: openai, anthropic, gemini, vertexai, google-vertex.
Dangling cross-resource references. An agent referencing a workflow ID, a workflow referencing an agent or surface, that isn't defined anywhere in your project.
Duplicate reference keys. Every workflow, agent, and surface needs a unique slug; two resources can't share one.
Invalid surface definitions. A Surface that fails its own structural validation (see Surfaces overview).
Workflow tool trigger must be a manual trigger. A workflow wrapped with defineWorkflowTool() has to point triggerNodeName at a manualTrigger step; any other trigger type is rejected.
Nesting depth. A reference chain deeper than three nodes, or a leaf workflow/agent that owns something it shouldn't at that depth. See Composing agents and workflows → How deep you can nest for the exact shapes.
Quick reference
| Error | What to check |
|---|---|
| Duplicate step | Every step id and name is unique in the workflow. |
| Missing connection | Every connected step is included in the steps array. |
| Invalid model | model is an object with provider, modelId, and credentialId. |
| Dangling reference | The workflow, agent, or surface you're referencing actually exists in your project. |
| Duplicate reference key | No two workflows, agents, or surfaces share a slug. |
| Workflow tool trigger | triggerNodeName names a manualTrigger step. |
| Nesting depth | The reference chain is at most three nodes, matching one of the two valid shapes. |