Bug
substituteWorkflowVariables() in packages/workflows/src/executor-shared.ts:250 defines the context variable pattern as:
export const CONTEXT_VAR_PATTERN_STR = '\\$(?:CONTEXT|EXTERNAL_CONTEXT|ISSUE_CONTEXT)';
This regex has no word boundary at the end. When a bash node or prompt uses a variable like $CONTEXT_FILE or $CONTEXT_NAME, the $CONTEXT prefix matches and gets replaced with the empty string (or the issue context), leaving _FILE or _NAME as bare text that bash interprets as a literal string or undefined variable.
Steps to reproduce
- Create a workflow with a bash node:
- id: example
bash: |
CONTEXT_FILE=".planning/phases/1/CONTEXT.md"
echo "$CONTEXT_FILE"
- Run the workflow. The bash receives:
_FILE=".planning/phases/1/CONTEXT.md"
echo "_FILE"
$CONTEXT was replaced with empty string, _FILE remains as the variable name. The output is the literal string _FILE, not the path.
Root cause
Line 316 in executor-shared.ts:
result = result.replace(new RegExp(CONTEXT_VAR_PATTERN_STR, 'g'), issueContext ?? '');
The pattern matches $CONTEXT as a prefix of $CONTEXT_FILE because there is no word-boundary anchor (\b) or negative lookahead ((?![A-Z_])) after the alternation group.
Suggested fix
Add a word boundary or negative lookahead:
// Option A: word boundary
export const CONTEXT_VAR_PATTERN_STR = '\\$(?:CONTEXT|EXTERNAL_CONTEXT|ISSUE_CONTEXT)\\b';
// Option B: negative lookahead for identifier continuation
export const CONTEXT_VAR_PATTERN_STR = '\\$(?:CONTEXT|EXTERNAL_CONTEXT|ISSUE_CONTEXT)(?![A-Za-z0-9_])';
Option B is more precise — it prevents matching when the variable name continues with valid identifier characters.
Impact
Any workflow bash node or prompt that uses a variable name starting with CONTEXT, EXTERNAL_CONTEXT, or ISSUE_CONTEXT (e.g. $CONTEXT_FILE, $CONTEXT_NAME, $CONTEXT_PATH) silently produces wrong values. The failure mode is particularly hard to debug because:
- No error is thrown
- The bash script still runs (with wrong variable names)
- Fallback defaults may mask the issue in some cases
Workaround
Rename variables to avoid the CONTEXT prefix: use CTX_FILE, CTX_NAME, etc.
Environment
- Archon v0.3.5
- Discovered while building custom DAG workflows with bash nodes that read
.planning/phases/$PHASE/CONTEXT.md
Bug
substituteWorkflowVariables()inpackages/workflows/src/executor-shared.ts:250defines the context variable pattern as:This regex has no word boundary at the end. When a bash node or prompt uses a variable like
$CONTEXT_FILEor$CONTEXT_NAME, the$CONTEXTprefix matches and gets replaced with the empty string (or the issue context), leaving_FILEor_NAMEas bare text that bash interprets as a literal string or undefined variable.Steps to reproduce
$CONTEXTwas replaced with empty string,_FILEremains as the variable name. The output is the literal string_FILE, not the path.Root cause
Line 316 in
executor-shared.ts:The pattern matches
$CONTEXTas a prefix of$CONTEXT_FILEbecause there is no word-boundary anchor (\b) or negative lookahead ((?![A-Z_])) after the alternation group.Suggested fix
Add a word boundary or negative lookahead:
Option B is more precise — it prevents matching when the variable name continues with valid identifier characters.
Impact
Any workflow bash node or prompt that uses a variable name starting with
CONTEXT,EXTERNAL_CONTEXT, orISSUE_CONTEXT(e.g.$CONTEXT_FILE,$CONTEXT_NAME,$CONTEXT_PATH) silently produces wrong values. The failure mode is particularly hard to debug because:Workaround
Rename variables to avoid the
CONTEXTprefix: useCTX_FILE,CTX_NAME, etc.Environment
.planning/phases/$PHASE/CONTEXT.md