Troubleshooting
Debugging guide for common workflow issues.
Table of Contents
- Workflow Won't Start
- Compilation Errors
- Job Failures
- Expression Errors
- Data Flow Issues
- Permission Issues
- Performance Issues
- Getting Help
Workflow Won't Start
Issue: Workflow Dispatch Fails
Error: Invalid input: budget must be a number
Diagnosis:
- Input validation failed during dispatch
- User provided wrong type
Solution:
1# Check workflow input schema
2curl https://workflow-engine-api.xema.dev/workflows/wf_123 \
3 -H "Authorization: Bearer $TOKEN" | jq '.data.triggers'
4
5# Correct the dispatch call
6curl -X POST https://workflow-engine-api.xema.dev/workflows/wf_123/dispatch \
7 -H "Authorization: Bearer $TOKEN" \
8 -d '{
9 "inputs": {
10 "budget": 100000 # Number, not string
11 }
12 }'Prevention:
- Define input types explicitly
- Use enums for closed sets
- Test dispatch before deploying
Compilation Errors
Issue: Unknown Action
Error: Action xema/unknown not found
Diagnosis:
- Action reference typo
- Action doesn't exist
- Version uses an unsupported range form
Solution:
1# ✅ Correct — omit the version to pin the current one at compile time
2uses: xema/agent
3
4# ✅ Correct — or pin an exact version
5uses: xema/[email protected]
6
7# ❌ Range — `@2.1` is a range, not an exact version; not supported
8uses: xema/[email protected]
9
10# ❌ Wrong action — this action does not exist
11uses: xema/undefinedA uses: reference is namespace/action with an optional exact @MAJOR.MINOR.PATCH version. Omit @<version> to pin the action's current version at compile time. Ranges (@2.1, ^2.1.0) are not supported — see the Language Reference.
Available Actions:
xema/agent— LLM agentxema/review— Draft + review loopxema/emit-artifact— Save artifactxema/decision-gate— Approval gatexema/webhook— Send webhookxema/http— HTTP request
Issue: Circular Dependencies
Error: Circular dependency detected: job1 → job2 → job1
Diagnosis:
- Jobs reference each other in
needs
Solution:
1❌ Bad:
2jobs:
3 job1:
4 needs: [job2]
5
6 job2:
7 needs: [job1] # Circular!
8
9✅ Fix:
10jobs:
11 job1:
12 uses: xema/agent
13
14 job2:
15 needs: [job1] # Linear dependencyIssue: Missing Required Input
Error: Missing required input: project_name
Diagnosis:
- Workflow definition requires input but dispatch didn't provide it
Solution:
1# In workflow.yaml
2on:
3 workflow_dispatch:
4 inputs:
5 project_name:
6 type: string
7 required: true1# In dispatch
2curl -X POST https://workflow-engine-api.xema.dev/workflows/wf_123/dispatch \
3 -H "Authorization: Bearer $TOKEN" \
4 -d '{
5 "inputs": {
6 "project_name": "Acme" # Provide required input
7 }
8 }'Job Failures
Issue: Job Timed Out
Error: Job 'analyze' exceeded timeout of 1h
Diagnosis:
- Job is taking longer than timeout
- External service is slow
Solution:
1# Increase timeout
2jobs:
3 slow-task:
4 timeout: '4h' # Was 1h
5 uses: xema/agentOr:
1# Increase default timeout
2defaults:
3 timeout: '4h'Debug:
1# Check job logs
2curl https://workflow-engine-api.xema.dev/runs/run_123/logs \
3 ?jobId=slow-task \
4 -H "Authorization: Bearer $TOKEN" | jq '.data.logs[]'Issue: Job Skipped After an Upstream Failure
Symptom: A job shows skipped although you expected it to run, or a
cleanup job did not run after a failure.
Diagnosis:
- A job with no status function in its
if:behaves assuccess() && (...): it is skipped when any job it needs failed, was cancelled or was skipped. - A skipped direct need also skips the job, so
if: ${{ true }}does not override it. needs.<job>.outcometells you which upstream ended how.
Solution: name the status function you mean.
1cleanup:
2 needs: [build]
3 if: ${{ always() }} # after success, failure, skip or cancel
4join:
5 needs: [fast-path, slow-path]
6 if: ${{ !failure() && !cancelled() }} # run even if one branch was skippedA run with any failed job still ends failed after its cleanup jobs finish.
Issue: Job Failed After Retries
Error: Job 'deploy' failed after 3 retries
Diagnosis:
- Job repeatedly failed
- Retry policy exhausted
Solution:
1# Increase retry attempts
2jobs:
3 deploy:
4 retry:
5 maxAttempts: 5 # Was 3
6 uses: xema/agentOr implement fallback:
1jobs:
2 primary-deploy:
3 uses: xema/agent
4
5 fallback-deploy:
6 if: ${{ failure() }}
7 uses: xema/agent
8 with:
9 strategy: fallbackDebug:
1# Get retry details
2curl https://workflow-engine-api.xema.dev/runs/run_123 \
3 -H "Authorization: Bearer $TOKEN" | jq '.data.jobs[] | select(.name=="deploy")'Expression Errors
Issue: Expression Syntax Error
Error: Invalid expression: ${{ inputs.name.toUpperCase() }}
Diagnosis:
- Expression contains invalid syntax
- Function doesn't exist
Solution:
1✅ Valid:
2${{ inputs.name }}
3${{ contains(inputs.name, 'test') }}
4${{ inputs.budget > 100000 }}
5
6❌ Invalid:
7${{ inputs.name.toUpperCase() }} # Method calls not supported
8${{ inputs.name | uppercase }} # Pipe not supported
9${{ inputs.name.. }} # Syntax errorIssue: Undefined Variable
Error: Variable 'projects' not found in context
Diagnosis:
- Referenced variable doesn't exist
- Typo in variable name
Solution:
1✅ Correct:
2${{ vars.organization }}
3${{ inputs.budget }}
4${{ needs.job1.outputs.summary }}
5
6❌ Wrong:
7${{ vars.org }} # Should be 'organization'
8${{ inputs.budge }} # Should be 'budget'
9${{ needs.job1.output }} # Should be 'outputs'Issue: Type Mismatch
Error: Cannot compare string with number: 'high' >= 100
Diagnosis:
- Expression compares incompatible types
Solution:
1✅ Correct types:
2${{ inputs.budget >= 100000 }} # Both numbers
3${{ inputs.priority == 'high' }} # Both strings
4
5❌ Type mismatch:
6${{ inputs.priority >= 100 }} # String vs number
7${{ inputs.budget == 'large' }} # Number vs stringData Flow Issues
Issue: Output Not Available
Error: Output 'summary' not found in job 'analyze'
Diagnosis:
- Job doesn't declare output
- Output name typo
- Accessing from non-dependent job
Solution:
1# Declare output
2jobs:
3 analyze:
4 uses: xema/agent
5 outputs:
6 summary: ${{ result.summary }} # Declare it
7
8 process:
9 needs: analyze
10 with:
11 summary: ${{ needs.analyze.outputs.summary }} # Then use itIssue: Matrix Outputs Not Expanding
Error: Cannot expand matrix output: needs.test.outputs is not array
Diagnosis:
- Matrix job didn't produce outputs
- Incorrect output syntax
Solution:
1jobs:
2 test-all:
3 strategy:
4 matrix:
5 version: [20, 21, 22]
6 uses: xema/agent
7 outputs:
8 result: ${{ result.output }} # Declare output
9
10 report:
11 needs: test-all
12 with:
13 # Correct: Access all outputs
14 results: ${{ needs.test-all.outputs[*] }}
15
16 # ❌ Wrong:
17 # results: ${{ needs.test-all.output }} # Missing 's'Issue: Webhook Payload Missing
Error: trigger.payload is null
Diagnosis:
- Workflow not triggered by webhook
- Accessing non-webhook context
Solution:
1# Only available in webhook triggers
2on:
3 webhook:
4 - event: scm.push
5
6jobs:
7 process:
8 uses: xema/agent
9 with:
10 # ✅ Available here
11 provider: ${{ trigger.provider }}
12
13 # ❌ Not available if triggered manuallyOr check trigger type:
1if: ${{ trigger.provider != null }} # Only if webhookPermission Issues
Issue: Permission Denied
Error: Insufficient permissions: 'write' permission required for 'backlog'
Diagnosis:
- Workflow doesn't have required permission
- Attempting operation beyond declared scope
Solution:
1# Add permission
2permissions:
3 backlog: write # Was: read
4
5jobs:
6 update-issue:
7 uses: xema/http
8 with:
9 url: https://jira.acme.com/...
10 method: PUTAvailable Scopes:
repos— SCM access (read, limited, write)kb— Knowledge base (read, limited, write)backlog— Issue tracking (read, limited, write)artifacts— Artifact store (read, limited, write)integrations— External integrations (read, limited, write)
Performance Issues
Issue: Workflow Too Slow
Error: Workflow took 8 hours to complete (expected < 2 hours)
Diagnosis:
- Sequential jobs that could be parallel
- Large matrix expansion
- Network timeouts
Solution - Parallelize:
1❌ Sequential:
2jobs:
3 build-backend:
4 uses: xema/agent
5
6 build-frontend:
7 needs: build-backend # Unnecessary dependency
8 uses: xema/agent
9
10✅ Parallel:
11jobs:
12 build-backend:
13 uses: xema/agent
14
15 build-frontend:
16 uses: xema/agent # No dependency
17
18 test-integration:
19 needs: [build-backend, build-frontend]
20 uses: xema/agentSolution - Limit Matrix:
1✅ Safe expansion:
2strategy:
3 dynamic:
4 from: ${{ needs.discover.outputs.services }}
5 maxEntries: 50 # Cap it!
6
7❌ Runaway:
8strategy:
9 dynamic:
10 from: ${{ needs.discover.outputs.services }}
11 # Could create 1000+ jobs!Issue: Too Many Concurrent Jobs
Error: Queue full: Too many jobs scheduled (max: 100)
Diagnosis:
- Matrix explosion
- Need to limit parallelism
Solution:
1strategy:
2 matrix:
3 version: [18, 19, 20, 21, 22]
4 maxParallel: 2 # Limit to 2 at a timeGetting Help
Check Workflow Status
1# Get workflow details
2curl https://workflow-engine-api.xema.dev/workflows/wf_123 \
3 -H "Authorization: Bearer $TOKEN" | jq
4
5# List recent runs
6curl https://workflow-engine-api.xema.dev/workflows/wf_123/runs \
7 -H "Authorization: Bearer $TOKEN" | jq '.data[]'
8
9# Get specific run
10curl https://workflow-engine-api.xema.dev/runs/run_123 \
11 -H "Authorization: Bearer $TOKEN" | jq
12
13# Get run logs
14curl https://workflow-engine-api.xema.dev/runs/run_123/logs \
15 -H "Authorization: Bearer $TOKEN" | jq '.data.logs'Debug Expressions
1# Test expression rendering
2curl -X POST https://deliverable-specs-api.xema.dev/deliverable-specs/test-render \
3 -H "Authorization: Bearer $TOKEN" \
4 -d '{
5 "expression": "${{ inputs.name }}",
6 "context": {
7 "inputs": { "name": "Test" }
8 }
9 }'Validate YAML
1# Local validation
2yamllint workflow.yaml
3
4# Validate against schema
5ajv validate -s workflow.schema.json -d workflow.yamlCommon Issues Checklist
- Input types match dispatch values
- Required inputs are provided
- Action names are correct
- No circular job dependencies
- Job dependencies use
needs - Outputs are declared before use
- Expressions have correct syntax
- Variables exist in scope
- Permissions cover required access
- Timeouts are reasonable
- Retry policies are defined
- Error handling (if, always, etc.)
Next: Decision Gate → — xema/decision-gate reference.