gastownhall/beads · error
neither '%s' nor '%s' found in epic text
Error message
neither '%s' nor '%s' found in epic text
What it means
After `parseDistillVar` splits the `--var` flag into a left and right side, at least one side must literally appear in the epic's searchable text so the command can decide which side is the variable name. If neither the left nor the right string is found in the epic text, the flag is ambiguous/invalid and distillation aborts.
Source
Thrown at cmd/bd/mol_distill.go:101
left, right := parts[0], parts[1]
leftFound := strings.Contains(searchableText, left)
rightFound := strings.Contains(searchableText, right)
switch {
case rightFound && !leftFound:
// spawn-style: --var branch=feature-auth
// left is variable name, right is the value to find
return right, left, nil
case leftFound && !rightFound:
// substitution-style: --var feature-auth=branch
// left is value to find, right is variable name
return left, right, nil
case leftFound && rightFound:
// Both found - prefer spawn-style (more natural guess)
// Agent likely typed: --var varname=concrete_value
return right, left, nil
default:
return "", "", fmt.Errorf("neither '%s' nor '%s' found in epic text", left, right)
}
}
type molDistillInput struct {
epicID string
formulaNameArg string
varFlags []string
dryRun bool
outputDir string
}
func gatherMolDistillInput(cmd *cobra.Command, args []string) molDistillInput {
in := molDistillInput{epicID: args[0]}
in.varFlags, _ = cmd.Flags().GetStringArray("var")
in.dryRun, _ = cmd.Flags().GetBool("dry-run")
in.outputDir, _ = cmd.Flags().GetString("output")
if len(args) > 1 {
in.formulaNameArg = args[1]View on GitHub (pinned to 71377f2769)
Solutions
- Read the epic (`bd show <epic-id>`) and use an exact substring of its text on one side of the `=`.
- Fix typos or case differences so one side of the flag matches text in the epic verbatim.
- Use the spawn-style `variable=value` form with an existing value, e.g. `--var epic_name=<exact text from epic>`.
Example fix
// before bd mol distill --epic bd-42 --var epic_name=AutH Refactor // after bd mol distill --epic bd-42 --var epic_name=Auth Refactor // exact text from the epic
Defensive patterns
Strategy: validation
Validate before calling
// shell: ensure one side of --var exists in the epic text before invoking
EPIC=$(bd show bd-42 --json | jq -r '.title + " " + .description')
VAR='epic_name=Auth Refactor'
L=${VAR%%=*}; R=${VAR#*=}
[[ "$EPIC" == *"$L"* || "$EPIC" == *"$R"* ]] || { echo "neither side found in epic text"; exit 1; }
bd mol distill --epic bd-42 --var "$VAR" Type guard
func varSideFound(flag, epicText string) bool {
p := strings.SplitN(flag, "=", 2)
if len(p) != 2 {
return false
}
return strings.Contains(epicText, p[0]) || strings.Contains(epicText, p[1])
} Try / catch
if err := runDistill(); err != nil && strings.Contains(err.Error(), "neither") {
fmt.Fprintln(os.Stderr, "use text that appears verbatim in the epic")
} Prevention
- Copy the match text directly from `bd show <epic-id>` output, never retype it.
- Remember the lookup is a case-sensitive substring search.
- Re-verify flags after editing or renaming an epic.
When it happens
Trigger: Running `bd mol distill --var 'foo=bar'` (from `distillSubgraph`) where neither `foo` nor `bar` occurs anywhere in the target epic's title/description text. Both `leftFound` and `rightFound` are false, so the `default` branch returns this error.
Common situations: Typos between the flag value and the epic text; the epic was renamed/edited after the command line was scripted; case mismatch (text search is case-sensitive); passing a variable name that only exists in your head, not in the epic content.
Related errors
- cannot use both --pull-only and --push-only
- %w (--prefer-local, --prefer-ado, --prefer-newer)
- --strategy %s contradicts --%s
- start must be >= 1
- end must be >= start
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/cc1dfa7d26bf7f38.
Report an issue: GitHub.