shareAI-lab/learn-claude-code · error · GoalError
goal condition cannot exceed {MAX_GOAL_LENGTH} characters
Error message
goal condition cannot exceed {MAX_GOAL_LENGTH} characters What it means
set_goal rejects conditions longer than MAX_GOAL_LENGTH = 4000 characters (s17_goal_loop/code.py:287). The condition is embedded in the evaluator's prompt each turn, so an oversized condition bloats every evaluation call; the hard cap keeps the evaluator prompt bounded and its verdicts reliable.
Source
Thrown at s17_goal_loop/code.py:287
):
if block_cap < 1:
raise GoalError("block_cap must be at least 1")
self.evaluator = evaluator
self.block_cap = block_cap
self.events = events if events is not None else []
self.active: GoalState | None = None
self.last_status: dict[str, Any] | None = None
self.consecutive_blocks = 0
def begin_query(self) -> None:
self.consecutive_blocks = 0
def set_goal(self, condition: str, tokens_at_start: int = 0) -> GoalState:
condition = condition.strip()
if not condition:
raise GoalError("goal condition cannot be empty")
if len(condition) > MAX_GOAL_LENGTH:
raise GoalError(
f"goal condition cannot exceed {MAX_GOAL_LENGTH} characters"
)
if self.active is not None:
self._record(
active=False,
met=False,
failed=False,
reason="replaced by a new goal",
)
self.active = GoalState(
condition=condition,
iterations=0,
set_at=time.time(),
tokens_at_start=tokens_at_start,
)
self.consecutive_blocks = 0
self._record(active=True, met=False, failed=False, reason="goal set")
return self.activeView on GitHub (pinned to 985456f4ad)
Solutions
- Distill the condition to a single verifiable predicate (one or two sentences)
- Split a large spec into the transcript (user message) and keep only the success criterion as the goal
- If a longer cap is genuinely needed, raise MAX_GOAL_LENGTH deliberately — but prefer trimming the condition
Example fix
# before
session.goal.set_goal(open("SPEC.md").read())
# after
session.goal.set_goal("SPEC.md: every requirement in the spec is implemented and tests/test_spec.py passes") Defensive patterns
Strategy: validation
Validate before calling
MAX_GOAL_LENGTH = 4000
condition = goal_text.strip()
if len(condition) > MAX_GOAL_LENGTH:
raise SystemExit(f"goal must be at most {MAX_GOAL_LENGTH} chars (got {len(condition)})")
controller.set_goal(condition) Type guard
def is_within_goal_limit(condition: str) -> bool:
return 0 < len(condition.strip()) <= 4000 Try / catch
try:
controller.set_goal(condition)
except GoalError as error:
if "cannot exceed" in str(error):
condition = summarize(condition) # distill to the success predicate
controller.set_goal(condition)
else:
raise Prevention
- Keep the goal a one-sentence verifiable predicate, not a spec dump
- Put large context in the query/transcript; keep only the success criterion as the goal
- Check len(goal) before calling set_goal when goals are generated programmatically
When it happens
Trigger: Calling set_goal with a condition over 4000 chars after stripping — e.g. pasting an entire spec document, a full file's contents, or a long transcript excerpt as the 'goal'.
Common situations: Using the goal field to smuggle context/instructions instead of a concise success predicate; programmatically generating the goal from a template that grows unbounded; concatenating many acceptance criteria into one string.
Related errors
- Max 20 todos
- Max 20 todos allowed
- MCP tool name is longer than 64 characters: {prefixed}
- goal evaluator must return a JSON object
- goal evaluator response requires non-empty 'reason'
AI-assisted analysis of shareAI-lab/learn-claude-code@985456f4ad (2026-08-14).
Data as JSON: /api/errors/445d23b4c03639dd.
Report an issue: GitHub.