gastownhall/beads · error
unknown condition type: %s
Error message
unknown condition type: %s
What it means
Condition.Evaluate dispatches on the Condition.Type field; if Type is not one of the three supported kinds (field, aggregate, external), evaluation fails with this error. The library only produces a Condition via ParseCondition, which always sets a valid Type, so this only fires when a Condition struct is constructed programmatically with a zero-value or invalid Type.
Source
Thrown at internal/formula/condition.go:241
Operator: Operator(m[2]),
Value: unquote(m[3]),
}, nil
}
return nil, fmt.Errorf("unrecognized condition format: %s", expr)
}
// Evaluate evaluates the condition against the given context.
func (c *Condition) Evaluate(ctx *ConditionContext) (*ConditionResult, error) {
switch c.Type {
case ConditionTypeField:
return c.evaluateField(ctx)
case ConditionTypeAggregate:
return c.evaluateAggregate(ctx)
case ConditionTypeExternal:
return c.evaluateExternal(ctx)
default:
return nil, fmt.Errorf("unknown condition type: %s", c.Type)
}
}
func (c *Condition) evaluateField(ctx *ConditionContext) (*ConditionResult, error) {
// Resolve step reference
stepID := c.StepRef
if stepID == "step" {
stepID = ctx.CurrentStep
}
step, ok := ctx.Steps[stepID]
if !ok {
return &ConditionResult{
Satisfied: false,
Reason: fmt.Sprintf("step %q not found", stepID),
}, nil
}
View on GitHub (pinned to 71377f2769)
Solutions
- Set Condition.Type explicitly to ConditionTypeField, ConditionTypeAggregate, or ConditionTypeExternal when constructing the struct
- Prefer building conditions with formula.ParseCondition(expr), which always assigns a valid Type
- Validate Type before calling Evaluate: switch on c.Type and reject anything outside the three constants
Example fix
// before
cond := &formula.Condition{StepRef: "review", Field: "status", Operator: formula.OpEqual, Value: "complete"}
res, err := cond.Evaluate(ctx) // unknown condition type:
// after
cond, err := formula.ParseCondition("review.status == 'complete'")
res, err := cond.Evaluate(ctx) Defensive patterns
Strategy: validation
Validate before calling
func validConditionType(c *formula.Condition) bool {
switch c.Type {
case formula.ConditionTypeField, formula.ConditionTypeAggregate, formula.ConditionTypeExternal:
return true
}
return false
}
if !validConditionType(cond) { return fmt.Errorf("condition type %q not supported", cond.Type) } Type guard
func isKnownConditionType(t formula.ConditionType) bool {
return t == formula.ConditionTypeField || t == formula.ConditionTypeAggregate || t == formula.ConditionTypeExternal
} Try / catch
res, err := cond.Evaluate(ctx)
if err != nil {
if strings.HasPrefix(err.Error(), "unknown condition type") {
return fmt.Errorf("condition misconfigured (type=%q): build via formula.ParseCondition", cond.Type)
}
return err
} Prevention
- Always construct conditions with formula.ParseCondition, never raw struct literals
- Check Type against the exported ConditionType constants before Evaluate
- Add a unit test round-tripping every condition string through ParseCondition
When it happens
Trigger: Calling Condition.Evaluate (or EvaluateCondition on a hand-built Condition) where Condition.Type is "" or an arbitrary string — e.g. `&formula.Condition{Field: "status", Operator: formula.OpEqual, Value: "complete"}` without setting Type.
Common situations: Building a Condition manually instead of via ParseCondition; forgetting to set Type after copying fields; custom code that constructs conditions from config data without mapping the type string to ConditionTypeField/Aggregate/External.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- unknown field: %s
- unknown aggregate function: %s
- unknown external type: %s
- parsing formula: %w
- resolving formula: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/9cf9db26746288b8.
Report an issue: GitHub.