HKUDS/Vibe-Trading · error · PlaybookError
playbook {path}: {key!r} must be a non-empty list of strings
Error message
playbook {path}: {key!r} must be a non-empty list of strings What it means
Raised by _string_list (agent/src/scheduled_research/playbooks.py:243) as PlaybookError when a frontmatter field that must be a non-empty list of strings is neither a string nor a non-empty list. A bare string is coerced to a one-element list; anything else (dict, int, null, empty list) fails with the playbook path and key name in the message.
Source
Thrown at agent/src/scheduled_research/playbooks.py:243
"name": self.name,
"description": self.description,
"suggested_schedule": self.suggested_schedule,
"suggested_timezone": self.suggested_timezone,
"markets": list(self.markets),
"data_capabilities": list(self.data_capabilities),
"variables": dict(self.variables),
}
if include_body:
data["body"] = self.body
return data
def _string_list(value: Any, key: str, path: Path) -> Tuple[str, ...]:
"""Coerce a frontmatter value to a tuple of non-empty strings."""
if isinstance(value, str):
value = [value]
if not isinstance(value, list) or not value:
raise PlaybookError(f"playbook {path}: {key!r} must be a non-empty list of strings")
items = tuple(str(item).strip() for item in value)
if any(not item for item in items):
raise PlaybookError(f"playbook {path}: {key!r} contains an empty entry")
return items
def load_playbook_file(path: Path) -> ResearchPlaybook:
"""Parse one playbook markdown file.
Args:
path: Path to a ``.md`` playbook file.
Returns:
The parsed :class:`ResearchPlaybook`.
Raises:
PlaybookError: If the filename is not a valid slug, the file has no
frontmatter, is missing a required key, declares a malformedView on GitHub (pinned to 80ffdda44c)
Solutions
- Fix the frontmatter so the field is a list of strings: tags: [news]
- For an optional field, remove the key entirely rather than leaving it empty
- Remember a single string is accepted and coerced — wrap multi-value entries in a YAML list
- Run load_playbook_file in CI/lint over all playbooks to catch this early
Example fix
# before (frontmatter) tags: # after tags: [news, research]
Defensive patterns
Strategy: validation
Validate before calling
def string_list_ok(value):
if isinstance(value, str):
return bool(value.strip())
return isinstance(value, list) and len(value) > 0 and all(
isinstance(i, str) and i.strip() for i in value
) Type guard
from typing import Any, Tuple
def as_string_list(value: Any) -> Tuple[str, ...]:
if isinstance(value, str):
value = [value]
if not isinstance(value, list) or not value:
return ()
return tuple(str(i).strip() for i in value if str(i).strip()) Try / catch
from agent.src.scheduled_research.playbooks import PlaybookError, load_playbook_file
try:
playbook = load_playbook_file(path)
except PlaybookError as exc:
if "must be a non-empty list of strings" in str(exc):
log.warning("skipping misconfigured playbook %s: %s", path, exc)
playbook = None
else:
raise Prevention
- Validate all playbook files with load_playbook_file in CI
- Delete optional frontmatter keys instead of leaving them empty
- Use YAML lists (dash items or [a, b]) for list fields
When it happens
Trigger: load_playbook_file on a playbook whose frontmatter has e.g. variables: {} instead of a list, tags: (empty), or tags: 3. YAML flow like 'tags:' with nothing after it parses as None and hits this too.
Common situations: Editing playbook markdown frontmatter and leaving a key empty; YAML indentation making an intended list parse as a scalar or dict; copy-pasting frontmatter between playbooks with different field shapes.
Related errors
- playbook {self.slug!r} has no variable {key!r}; declared: {s
- playbook variable {key!r} is {len(text)} chars; the cap is {
- source.playbook_slug is required
- source.variables must be an object
- invalid alpha_id
AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28).
Data as JSON: /api/errors/89214848859f39fe.
Report an issue: GitHub.