Documentation
Fix validation errors
Development docs · main. Your installed version may differ.
Find the message you see, then follow its fix. Each message is an error in both modes, or a warning that only fails strict validation: see Lenient and strict.
Errors vs Warnings
Section titled “Errors vs Warnings”Understanding which issues are hard errors and which are warnings helps you prioritize fixes.
Always Errors (Both Modes)
Section titled “Always Errors (Both Modes)”These issues always block template use:
| Issue | Example Message |
|---|---|
Total ≠ configured totalEstimationMustBe | Total estimation is 70%, but must be 100% |
Estimation outside configured totalEstimationRange | Total estimation is 80%, must be 95%-105% |
| Task count below minimum | Template has 1 task(s), but minimum is 3 |
| Task count above maximum | Template has 12 task(s), but maximum is 10 |
| Non-existent dependency reference | Task depends on non-existent task ID: "setup-db" |
Task uses dependsOn but has no id | Task "Create API" has dependencies but no id field |
| Circular dependency | Circular dependency detected: task1 -> task2 -> task1 |
| Missing required field | Task title is required |
| Invalid email format | Invalid email: bad-email |
| Wrong field type | Expected number but received string |
| Negative estimation | Estimation percentage cannot be negative |
Final percentage outside taskEstimationRange | Final task allocation is 50%, but must be between 10% and 30%. |
Inverted taskEstimationRange bounds | taskEstimationRange.max must be greater than or equal to min. |
| Invalid custom field in Online Validation | Field "Custom.ClientTier" not found for work item type "Task" |
Tag condition with an operator other than contains/not-contains | Field "tags" is multi-value; only "contains"/"not-contains" are supported (got "equals"). |
Both or neither of conversion.factor and conversion.table | conversion must set exactly one of factor or table |
defaultParentEstimation the conversion can't convert | defaultParentEstimation "XXL" is not a key of conversion.table |
| Estimation source, task type or target field missing in Online Validation | Field "Custom.TShirtSize" not found for work item type "User Story". |
| Target field that can't hold a Task Estimate (not numeric, or a picklist) in Online Validation | Field "Custom.Notes" is a string field; Task Estimates can only be written to numeric fields. |
Warnings (Errors in Strict Mode)
Section titled “Warnings (Errors in Strict Mode)”These issues are warnings in lenient mode but become errors in strict mode:
| Issue | Example Message |
|---|---|
| Offline custom field verification | 1 task(s) have custom fields that could not be verified |
Total estimation not 100% (no totalEstimationMustBe or totalEstimationRange configured) | Total estimation is 70% (expected 100%) |
| Task missing recommended field | Task "Implementation" has no activity set |
| Template has no filter criteria | No filter criteria configured: template will match all work items |
| Story Estimate value with no conversion (Online) | "XXL" is a valid value of "Custom.TShirtSize" but has no conversion; Stories with it will get blank Task Estimates. |
conversion.table key that isn't an allowed value (Online) | conversion.table key "XXS" is not an allowed value of "Custom.TShirtSize" and will never match. |
| Free-text or open picklist source field (Online) | "Custom.Size" is a free-text field; any value not in the conversion table will leave Tasks unestimated. |
| Numeric condition on a text Story Estimate (Online) | This condition compares estimation numerically, but "Custom.TShirtSize" holds text values; ... |
| Target field that holds a ranking or value (Online) | Field "Microsoft.VSTS.Common.BacklogPriority" holds a ranking or value, not effort; ... |
Some warnings stay warnings in strict mode, because the Template still works as intended. One example is the deprecated minimumTaskPoints key, which is used as minimumTaskEstimate.
Estimation Errors
Section titled “Estimation Errors”Total Estimation Does Not Equal 100%
Section titled “Total Estimation Does Not Equal 100%”Note: Without
totalEstimationMustBeortotalEstimationRangeconfigured, a mismatched total is a warning (not an error) in lenient mode: the template is still usable. It only becomes an error when a strict constraint is configured, or when running in strict mode.
Error Message (when totalEstimationMustBe: 100 is set):
Total estimation is 70%, but must be 100%.💡 Add 30% to existing tasks or create a new task with 30% estimation.Cause: Your task estimation percentages don't add up to 100%, and a strict validation constraint requires them to.
A repeated task counts once per copy: repeat: 4 at 10% adds 40% to the total. When the template has repeated tasks, the suggestion ends with "Each copy of a repeated task counts toward this total."
Solutions:
-
Adjust existing tasks:
tasks:- title: "Design"estimationPercent: 40 # Was 30- title: "Development"estimationPercent: 60 # Was 40 -
Add a new task:
tasks:- title: "Design"estimationPercent: 30- title: "Development"estimationPercent: 40- title: "Testing" # New taskestimationPercent: 30
Total Estimation Exceeds 100%
Section titled “Total Estimation Exceeds 100%”Error Message:
Total estimation is 120%, but must be 100%.💡 Reduce task estimations by 20% to reach 100%.Cause: Your task estimation percentages exceed 100%.
Solutions:
-
Reduce task percentages proportionally:
tasks:- title: "Design"estimationPercent: 25 # Was 40- title: "Development"estimationPercent: 50 # Was 60- title: "Testing"estimationPercent: 25 # Was 20 -
Use the wizard's auto-normalization feature:
Terminal window atomize template create --scratch# The wizard will offer to normalize estimations automatically -
Let generation scale the percentages: set
estimation.normalize: alwaysto scale them to exactly 100% when tasks are created. The default,auto, scales totals below 100% up (for example when a conditional task is skipped) but keeps totals above 100% unless you choose to normalize when the CLI asks.neveralways uses the percentages as written. This changes how tasks are generated, not this validation message, so also relaxtotalEstimationMustBeortotalEstimationRangeif you've set one.
Estimation Outside Range
Section titled “Estimation Outside Range”Error Message:
Total estimation is 80%, but must be between 95% and 105%.💡 Increase task estimations by 15% to meet the minimum of 95%.Cause: Total estimation falls outside the configured acceptable range.
Solution:
tasks: - title: "Task 1" estimationPercent: 50 # Increase from 40 - title: "Task 2" estimationPercent: 45 # Increase from 40Negative or Excessive Estimation
Section titled “Negative or Excessive Estimation”Error Message:
Estimation percentage cannot be negative.💡 Estimation percentage cannot be negative. Use a value between 0 and 100.Cause: Task has invalid estimation value (negative or > 100).
Solution:
tasks: - title: "Task 1" estimationPercent: 50 # Fix: was -10 or 150Conversion Errors
Section titled “Conversion Errors”Error Messages:
conversion must set exactly one of factor or tableconversion.multipliers requires conversion.tableconversion.multipliers cannot be used when every table key is numeric: '25' would be ambiguous between the key 25 and 2 × 5Cause: estimation.conversion turns the Story Estimate into Task hours with either a factor or a table, not both. multipliers (accepting values such as 0.3XL) only works with a table of non-numeric sizes.
Solution:
estimation: source: "Custom.TShirtSize" conversion: table: { S: 4, M: 8, L: 20, XL: 40 } multipliers: trueDefault Story Estimate Can't Be Converted
Section titled “Default Story Estimate Can't Be Converted”Error Message:
defaultParentEstimation "XXL" is not a key of conversion.tabledefaultParentEstimation "M" is not numeric and no conversion.table is setCause: defaultParentEstimation is the Story Estimate assumed with ifParentHasNoEstimation: use-default, so it has to go through the same conversion as a real one.
Solution: Use one of the table's keys, or a number when there is no table.
Deprecated minimumTaskPoints
Section titled “Deprecated minimumTaskPoints”Warning Messages:
minimumTaskPoints is deprecated; the minimum applies in the Task's unit, which may not be points.Both minimumTaskEstimate and the deprecated minimumTaskPoints are set; minimumTaskEstimate (0.5) is used and minimumTaskPoints (1) is ignored.Cause: The minimum is applied to the Task Estimate (hours by default), so it was renamed. The old key still works.
Solution: Rename the key to minimumTaskEstimate, or remove the duplicate. In VS Code, the quick fix does this for you.
Estimation Fields in Online Validation
Section titled “Estimation Fields in Online Validation”Online Validation (atomize validate --profile <name>) checks the estimation settings against your project.
Errors:
Field "Custom.TShirtSize" not found for work item type "User Story".Work item type "Sub-task" does not exist in this project. Available types: Bug, Task, User Story.Field "Custom.Effort" not found for work item type "Task".Field "Custom.Notes" is a string field; Task Estimates can only be written to numeric fields.Field "Custom.Points" only accepts a fixed list of values, so calculated Task Estimates can't be written to it.Warnings (errors in strict mode):
"XXL" is a valid value of "Custom.TShirtSize" but has no conversion; Stories with it will get blank Task Estimates.conversion.table key "XXS" is not an allowed value of "Custom.TShirtSize" and will never match."Custom.Size" is a free-text field; any value not in the conversion table will leave Tasks unestimated.Field "Microsoft.VSTS.Common.BacklogPriority" holds a ranking or value, not effort; writing Task Estimates to it will overwrite that.Solutions:
- Check the reference names of
estimation.source,taskTypeandtargetFields. When connected, the valid fields are offered by the CLI wizard. - Write Task Estimates only to writable number fields that aren't picklists, such as
Microsoft.VSTS.Scheduling.RemainingWorkor a custom decimal field. - Make
conversion.tablekeys match the field's allowed values exactly, and add a row for every value your Stories use. - With a saved-query filter, declare
workItemTypesso the source field is checked against the right type.
Task Count Errors
Section titled “Task Count Errors”Too Few Tasks
Section titled “Too Few Tasks”Error Message:
Template has 1 task(s), but minimum is 3. Add 2 more task(s).💡 Add 2 more task(s) to meet the minimum requirement of 3 tasks.Cause: Template doesn't have enough tasks to meet minimum requirement.
Each copy of a repeated task counts, so one task with repeat: 3 counts as 3. When the template has repeated tasks, the message says "(counting each repeated copy)", and the suggestion also offers raising a repeat count.
Solution:
validation: minTasks: 3
tasks: - title: "Task 1" estimationPercent: 33 - title: "Task 2" # Added estimationPercent: 33 - title: "Task 3" # Added estimationPercent: 34Too Many Tasks
Section titled “Too Many Tasks”Error Message:
Template has 5 task(s), but maximum is 3. Remove 2 task(s) or increase maxTasks.💡 Remove 2 task(s) or increase the maxTasks limit to 5.Cause: Template has more tasks than the maximum allowed.
Each copy of a repeated task counts. With repeated tasks the message reads, for example:
Template has 6 task(s) (counting each repeated copy), but maximum is 4. Remove 2 task(s) or increase maxTasks.💡 Remove 2 task(s), lower a repeat count, or increase the maxTasks limit to 6.Solutions:
-
Remove excess tasks:
tasks:- title: "Task 1"- title: "Task 2"- title: "Task 3"# Removed Task 4 and Task 5 -
Increase the limit:
validation:maxTasks: 5 # Increased from 3
At Least One Task Required
Section titled “At Least One Task Required”Error Message:
At least one task is required💡 Add at least one task to the template.Cause: Template has no tasks defined.
Solution:
tasks: - title: "Initial Task" description: "First task description" estimationPercent: 100Dependency Errors
Section titled “Dependency Errors”Non-Existent Task Dependency
Section titled “Non-Existent Task Dependency”Error Message:
Task depends on non-existent task ID: "setup-db". Available task IDs: "task1", "task2"💡 Either add a task with id: "setup-db" or update the dependsOn field to reference an existing task ID.Cause: A task references a dependency that doesn't exist.
Solutions:
-
Fix the dependency reference:
tasks:- id: "task1"title: "Setup Database"estimationPercent: 30- id: "task2"title: "Create API"estimationPercent: 70dependsOn: ["task1"] # Fixed: was "setup-db" -
Add the missing task:
tasks:- id: "setup-db" # Added missing tasktitle: "Setup Database"estimationPercent: 30- id: "task2"title: "Create API"estimationPercent: 70dependsOn: ["setup-db"]
Task Has Dependencies But No ID
Section titled “Task Has Dependencies But No ID”Error Message:
Task "Create API" has dependencies but no id field.💡 Add an 'id' field to this task, e.g., 'id: "create-api"'Cause: A task specifies dependencies but doesn't have an ID itself.
Solution:
tasks: - id: "setup-db" title: "Setup Database" estimationPercent: 30 - id: "create-api" # Added missing ID title: "Create API" estimationPercent: 70 dependsOn: ["setup-db"]Task Referenced But Has No ID
Section titled “Task Referenced But Has No ID”Error Message:
Task "Setup Database" is referenced by other tasks but has no id field.💡 Add 'id: "setup-database"' to this task. Referenced by: "Create API", "Write Tests"Cause: Other tasks depend on this task, but it doesn't have an ID.
Solution:
tasks: - id: "setup-database" # Added ID title: "Setup Database" estimationPercent: 30 - id: "create-api" title: "Create API" estimationPercent: 40 dependsOn: ["setup-database"] - id: "write-tests" title: "Write Tests" estimationPercent: 30 dependsOn: ["setup-database"]Circular Dependencies
Section titled “Circular Dependencies”Error Message:
Circular dependency detected: task1 -> task2 -> task1Break the circular dependency by removing one of these dependencies: "task1" depends on "task2", "task2" depends on "task1"Cause: Tasks have circular dependency relationships.
Solution:
# Before (circular):tasks: - id: "task1" title: "Task 1" dependsOn: ["task2"] # ❌ Circular! - id: "task2" title: "Task 2" dependsOn: ["task1"] # ❌ Circular!
# After (fixed):tasks: - id: "task1" title: "Task 1" # No dependencies - id: "task2" title: "Task 2" dependsOn: ["task1"] # ✅ Linear dependencyRepeat Errors
Section titled “Repeat Errors”These errors come from a task's repeat count.
Repeat Above the Limit
Section titled “Repeat Above the Limit”Error Message:
Task repeats 25 times, but the maximum is 20. Lower repeat or raise validation.maxRepeat.💡 Lower the repeat count, or raise validation.maxRepeat if the template genuinely needs more copies.Cause: A task's repeat is above the template's limit, which is 20 unless validation.maxRepeat sets another value. The limit guards against a typo creating many Tasks at once.
Solutions:
-
Lower the count:
tasks:- title: "Add review conclusions"estimationPercent: 4repeat: 20 # Was 25 -
Raise the limit when the template really needs more copies:
validation:maxRepeat: 25
Repeated Task With Dependencies
Section titled “Repeated Task With Dependencies”Error Message:
A repeated task cannot have dependsOn. Remove repeat or dependsOn from this task.💡 Remove dependsOn from the repeated task, or remove repeat and define each copy as its own task.Cause: A task has both repeat and dependsOn. A dependency links two single Work Items, and a repeated task's copies have no single Work Item to link.
Solutions:
-
Drop the dependency:
tasks:- id: "implement"title: "Implement"estimationPercent: 60- title: "Add review conclusions"estimationPercent: 10repeat: 4 # dependsOn removed -
Write the copies as separate tasks when each needs its own dependency.
Dependency on a Repeated Task
Section titled “Dependency on a Repeated Task”Error Message:
Task depends on "review", which is repeated. A task cannot depend on a repeated task.💡 Remove "review" from dependsOn, or remove repeat from task "review".Cause: A task lists a repeated task's id in its dependsOn. There's no single copy to depend on.
Solution:
tasks: - id: "review" title: "Add review conclusions" estimationPercent: 10 repeat: 4 - id: "merge" title: "Merge" estimationPercent: 60 # dependsOn: ["review"] removedInvalid Repeat Count
Section titled “Invalid Repeat Count”Error Message:
Repeat count must be at least 1Repeat count must be a whole numberCause: repeat is 0, negative or fractional. Use a whole number of at least 1, or remove repeat for a single Task.
Condition Errors
Section titled “Condition Errors”Invalid Condition Syntax
Section titled “Invalid Condition Syntax”Error Message:
Invalid input for condition💡 Conditions use structured objects such as `field`, `customField`, `all`, and `any`.Cause: Condition uses the old string expression syntax instead of the structured condition format Atomize validates now.
Solutions:
-
Use story variables:
tasks:- title: "Backend Task"estimationPercent: 50condition:field: "tags"operator: "contains"value: "backend" -
Use custom fields:
tasks:- title: "High Priority Task"estimationPercent: 30condition:customField: "Custom.Priority"operator: "equals"value: "High" -
Combine conditions:
tasks:- title: "Complex Condition"estimationPercent: 40condition:all:- field: "tags"operator: "contains"value: "api"- field: "estimation"operator: "gt"value: 5
Valid Operators:
contains/not-containsequals/not-equalsgt/lt/gte/lteall/any
Unsupported Operator on Tags
Section titled “Unsupported Operator on Tags”Error Message:
Field "tags" is multi-value; only "contains"/"not-contains" are supported (got "equals").Cause: A Story has many tags, so a tag condition can only check whether one is present.
Solution:
condition: field: "tags" operator: "contains" # was: equals value: "backend"Numeric Operator on a Non-Numeric Story Estimate
Section titled “Numeric Operator on a Non-Numeric Story Estimate”Error Message (at generation, the task is skipped):
cannot compare the Story Estimate "L" with "gt" because it is not numeric; use equals or not-equals for categoriesOnline Validation warns about this before you generate:
This condition compares estimation numerically, but "Custom.TShirtSize" holds text values; it will skip the task for any non-numeric Story Estimate.Cause: field: estimation compares the raw Story Estimate, before any conversion. When it is a size such as L, gt/lt/gte/lte have nothing to compare.
Solution: Compare categories by value:
condition: any: - { field: "estimation", operator: "equals", value: "L" } - { field: "estimation", operator: "equals", value: "XL" }Schema Errors
Section titled “Schema Errors”Missing Required Field
Section titled “Missing Required Field”Error Message:
Task title is required💡 This field cannot be empty. Please provide a value.Cause: A required field is missing or empty.
Solution:
tasks: - title: "My Task" # Added required title estimationPercent: 100Invalid Email Format
Section titled “Invalid Email Format”Error Message:
Invalid email💡 Use a valid email address format (e.g., user@example.com) or the special value "@Me".Cause: Email field has invalid format.
Solutions:
-
Use valid email:
filter:assignedTo: ["john.doe@example.com"] -
Use @Me macro:
filter:assignedTo: ["@Me"] # Refers to current user
Type Mismatch
Section titled “Type Mismatch”Error Message:
Expected a number but received string.💡 Expected a number but received string. Remove quotes from numeric values.Cause: Field has wrong type (e.g., string instead of number).
Solutions:
# Wrong:tasks: - title: "Task" estimationPercent: "50" # ❌ String
# Correct:tasks: - title: "Task" estimationPercent: 50 # ✅ NumberUnderstanding Error Messages
Section titled “Understanding Error Messages”Error Message Format
Section titled “Error Message Format”Each finding names the part of the Template it's about, followed by the message:
Template validation failed [Lenient]
Errors: • tasks: Total estimation is 70%, but must be 100%. • tasks.0.dependsOn: Task depends on non-existent task ID: "design".
Fix the errors above and try again.tasks.0 is the first task. Most findings also carry a suggested fix. The VS Code Validation Report shows it under each finding, and atomize validate --output json includes it as suggestion:
{"path":"tasks","message":"Total estimation is 70%, but must be 100%.","code":"INVALID_TOTAL_ESTIMATION","suggestion":"Add 30% to existing tasks or create a new task with 30% estimation."}Error vs Warning
Section titled “Error vs Warning”- Errors block the Template from being used. Fix them.
- Warnings don't block it in lenient mode, but the Template may not behave as you expect. In strict mode they are errors too.
A valid Template with warnings reports them after its summary:
Template is valid! [Lenient]
Warnings: • tasks[*].customFields: 1 task(s) have custom fields that could not be verified. Run with --profile <name> (or choose Online when prompted) to validate field names, types, and picklist values.Validation Commands
Section titled “Validation Commands”Validate a template:
atomize validate my-template.yamlStrict validation (promotes warnings to errors):
atomize validate my-template.yaml --strictValidation in CI/CD: atomize validate checks one Template per run and exits with 0 when it's valid and 1 when it isn't.
for template in templates/*.atomize.yaml; do atomize validate "$template" --strict || exit 1doneecho "All templates valid!"Quick Reference
Section titled “Quick Reference”| Error Type | Key Indicator | Quick Fix |
|---|---|---|
| Estimation too low | "Add X%" | Increase task percentages or add tasks |
| Estimation too high | "Reduce X%" | Decrease task percentages |
| Too few tasks | "Add X more task(s)" | Add more tasks |
| Too many tasks | "Remove X task(s)" | Remove tasks or increase limit |
| Invalid dependency | "non-existent task ID" | Fix ID or add missing task |
| Missing ID | "no id field" | Add id: "task-name" |
| Circular dependency | "Circular dependency detected" | Remove one dependency from cycle |
| Repeat too high | "Task repeats X times, but the maximum is Y" | Lower repeat or raise validation.maxRepeat |
| Repeat with dependencies | "A repeated task cannot have dependsOn" | Remove dependsOn or repeat |
| Depends on a repeated task | "which is repeated" | Remove it from dependsOn |
| Invalid condition | "structured object" | Use field / customField conditions |
| Tag operator | "is multi-value" | Use contains / not-contains |
| Category estimate compared numerically | "is not numeric" | Use equals / not-equals with the size |
| Conversion | "exactly one of factor or table" | Keep either factor or table |
| Estimation field (Online) | "not found for work item type" | Fix the reference name or workItemTypes |
| Uncovered size (Online) | "has no conversion" | Add the value to conversion.table |
| Deprecated key | "minimumTaskPoints is deprecated" | Rename to minimumTaskEstimate |
| Invalid email | "Invalid email" | Use valid email or "@Me" |
| Wrong type | "Expected X but received Y" | Fix value type (number vs string) |
Getting Help
Section titled “Getting Help”If you encounter an error not covered here:
- Check the error message suggestion - It often contains the exact fix needed
- Run with --strict - Promotes warnings to errors for a complete picture
- Use the template wizard - Interactive mode catches errors as you type
- Validate incrementally - Test after each change
Report Issues:
- GitHub: https://github.com/Simao-Pereira-Gomes/Atomize/issues
- Include: Error message, template YAML, and validation output