HKUDS/Vibe-Trading · error · ValueError
portfolio source labels must contain 1 to 80 printable chara
Error message
portfolio source labels must contain 1 to 80 printable characters
What it means
Each source's label (explicit or inherited from the connection) must be 1-80 characters with no control characters (< 0x20). Empty, over-length, or control-character labels are rejected during parsing.
Source
Thrown at agent/src/portfolio/config.py:189
legacy_profile.id,
str(raw.get("label") or legacy_profile.label),
)
else:
connection = store.get(connection_id)
profile = profile_by_id(connection.profile_id)
if profile not in eligible_profiles():
raise ValueError(
f"connection is not eligible for read-only portfolios: {connection_id}"
)
if connection_id in seen_ids:
raise ValueError("portfolio connection ids must be unique")
label = str(raw.get("label") or connection.label).strip()
if (
not label
or len(label) > 80
or any(ord(character) < 32 for character in label)
):
raise ValueError(
"portfolio source labels must contain 1 to 80 printable characters"
)
seen_ids.add(connection_id)
sources.append(
PortfolioSource(
connection_id=connection_id,
label=label,
enabled=bool(raw.get("enabled", True)),
order=int(raw.get("order", index)),
include_cash=bool(raw.get("include_cash", True)),
)
)
return PortfolioSettings(
display_currency=currency,
sources=tuple(sorted(sources, key=lambda item: (item.order, item.id))),
)
View on GitHub (pinned to 80ffdda44c)
Solutions
- Set a concise label (1-80 printable characters)
- Truncate generated labels: label[:80]
- Strip control characters from pasted text before saving
Example fix
# before
{"connection_id": "binance-main", "label": ""}
# after
{"connection_id": "binance-main", "label": "Binance main account"} Defensive patterns
Strategy: validation
Validate before calling
label = ''.join(ch for ch in (label or '').strip() if ord(ch) >= 32)[:80]
if not label:
label = cid # fallback to the connection id itself
entry['label'] = label Type guard
def is_valid_label(label) -> bool:
return bool(label) and len(label) <= 80 and all(ord(c) >= 32 for c in label) Try / catch
try:
settings = parse_settings(payload, store)
except ValueError as exc:
if 'labels must contain' in str(exc):
for e in payload['sources']:
e['label'] = sanitize_label(e.get('label')) or (e.get('connection_id') or 'source')
settings = parse_settings(payload, store) Prevention
- Always set explicit labels when generating source entries
- Truncate generated labels to 80 chars
- Strip pasted control characters before saving
When it happens
Trigger: label = '', ' ' (after strip), an 81+ character label, labels containing '\n'/'\t'/null bytes, or a connection whose stored label is blank so the fallback fails too.
Common situations: Omitting labels assuming defaults exist, pasting multi-line text into a label field, unicode paste introducing control chars, or scripted configs generating labels from unbounded strings.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- display_currency must be USD or CNY
- timezone must be a non-empty IANA timezone key or null
- invalid alpha_id
- alpha_id not found
- invalid period: {exc}
AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28).
Data as JSON: /api/errors/3ee5af3876d3d787.
Report an issue: GitHub.