Skip to content

Variable substitution matches $CONTEXT as prefix of $CONTEXT_FILE — no word boundary #1112

@jonasvanderhaegen

Description

@jonasvanderhaegen

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

  1. Create a workflow with a bash node:
- id: example
  bash: |
    CONTEXT_FILE=".planning/phases/1/CONTEXT.md"
    echo "$CONTEXT_FILE"
  1. 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions