langchain-ai/deepagents · error · ValueError
--rubric must not be empty.
Error message
--rubric must not be empty.
What it means
`_resolve_rubric_text` raises `ValueError` when the inline `--rubric` string is empty or whitespace-only. Like the file variant, an empty inline rubric is rejected because it would make the run effectively rubric-less.
Source
Thrown at libs/code/deepagents_code/main.py:1543
try:
text = Path(path).expanduser().read_text(encoding="utf-8")
except (OSError, UnicodeError) as exc:
# `UnicodeError` (e.g. `UnicodeDecodeError`) subclasses `ValueError`,
# not `OSError`. Catch it here so a binary/non-UTF-8 file yields the
# framed "Could not read rubric file" message instead of a raw codec
# error.
msg = f"Could not read rubric file {path!r}: {exc}."
raise ValueError(msg) from exc
if not text.strip():
msg = f"Rubric file {path!r} is empty."
raise ValueError(msg)
resolved = text.strip()
validate_rubric(resolved)
return resolved
if not rubric.strip():
msg = "--rubric must not be empty."
raise ValueError(msg)
resolved = rubric.strip()
validate_rubric(resolved)
return resolved
# The standalone `validate_rubric` above is sufficient here, unlike `/rubric next`,
# which additionally runs the combined notice check via `_next_rubric_size_error`.
# That check exists because an in-session one-shot rubric is embedded in the notice
# beside an actionable goal's objective and status note, and the pair can exceed
# `GOAL_NOTICE_TEXT_CHAR_LIMIT` even when each fits alone. `--rubric` cannot reach
# that state: it requires `-n`, and `run_non_interactive` takes no resume or
# thread-id argument, so it always starts a fresh thread with no checkpointed goal.
# `--goal` is rejected alongside `--rubric` and is interactive-only, so no goal
# objective can be set on this path either. Add the combined check here if the
# non-interactive path ever gains thread resumption.
def _warn_if_interpreter_tools_without_interpreter(View on GitHub (pinned to a1af029e6e)
Solutions
- Set the rubric text explicitly: `dcode --rubric "<your rubric>"`
- Guard shell usage: `[ -n "$RUBRIC" ] || { echo 'RUBRIC is empty'; exit 1; }` before invoking
- Use `--rubric-file` pointing to a non-empty file instead of inline text
Example fix
// before
dcode --rubric "$RUBRIC" # RUBRIC unset -> empty string
// after
[ -n "$RUBRIC" ] || { echo "RUBRIC is empty" >&2; exit 1; }
dcode --rubric "$RUBRIC" Defensive patterns
Strategy: validation
Validate before calling
import os
rubric = os.environ.get("RUBRIC", "")
if not rubric.strip():
raise SystemExit("RUBRIC is empty; refusing to launch") Try / catch
try:
rubric = _resolve_rubric_text(args)
except ValueError as exc:
raise SystemExit(f"bad rubric input: {exc}") Prevention
- Use `${RUBRIC:?}` in shell scripts to fail fast on unset variables
- Quote inline rubric text carefully to avoid losing it in shell parsing
- Prefer --rubric-file over inline strings for long or scripted rubrics
When it happens
Trigger: `cli_main --rubric ""` or `--rubric " "` — typically from a shell variable that failed to expand (`--rubric "$RUBRIC"` with unset `RUBRIC`) or a script that builds the flag conditionally and drops the content.
Common situations: Unset/empty environment variable interpolated into the flag; CI pipeline where the rubric artifact step was skipped; copy-paste losing the quoted text.
Related errors
- Rubric file {path!r} is empty.
- Cannot combine 'all' with other commands in --shell-allow-li
- cli_max_retries must be >= 0, got {self.cli_max_retries}
- Error: Invalid skill name: {error_msg}
- Error: {path_error}
AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29).
Data as JSON: /api/errors/6a9bd2e09942ab7e.
Report an issue: GitHub.