langgenius/dify · warning
{str(exc)}
Error message
{str(exc)} What it means
Flask `abort(400, description=str(exc))` (HTTP 400) raised inside `_parse_observability_time_range` (api/controllers/console/agent/roster.py:538). It wraps `libs.datetime_utils.parse_time_range`, which raises ValueError on malformed time strings (expected format `YYYY-MM-DD HH:MM`), invalid timezone names, or when start > end. The helper uses `account.timezone or 'UTC'` as the timezone.
Source
Thrown at api/controllers/console/agent/roster.py:538
info_endpoint=f"{base_url}/info",
meta_endpoint=f"{base_url}/meta",
api_rpm=app_model.api_rpm or 0,
api_rph=app_model.api_rph or 0,
api_key_count=_agent_api_key_count(session, str(app_model.id)),
)
return response.model_dump(mode="json")
def _agent_observability_service(session: Session) -> AgentObservabilityService:
return AgentObservabilityService(session)
def _parse_observability_time_range(start: str | None, end: str | None, account: Account):
timezone = account.timezone or "UTC"
try:
return parse_time_range(start, end, timezone)
except ValueError as exc:
abort(400, description=str(exc))
def _query_values(name: str, alias_name: str | None = None) -> list[str]:
def _get_values(field_name: str) -> list[str]:
values = request.args.getlist(field_name)
indexed_values: list[tuple[int, list[str]]] = []
prefix = f"{field_name}["
for key in request.args:
if not key.startswith(prefix) or not key.endswith("]"):
continue
index = key[len(prefix) : -1]
if index.isdigit():
indexed_values.append((int(index), request.args.getlist(key)))
for _, items in sorted(indexed_values):
values.extend(items)
return values
values = _get_values(name)View on GitHub (pinned to ef8544b173)
Solutions
- Send `start` and `end` in the exact `YYYY-MM-DD HH:MM` format with URL encoding for the space.
- Ensure `start <= end` and that both fall on valid calendar dates.
- Verify the user's account timezone is a valid IANA name; rely on the 'UTC' fallback only if unset.
Example fix
// before GET /agent/<id>/logs?start=2024-01-01&end=2024-02-01 // after (correct format with encoded space) GET /agent/<id>/logs?start=2024-01-01%2000:00&end=2024-02-01%2000:00
Defensive patterns
Strategy: validation
Validate before calling
import datetime, pytz
TIME_FMT = "%Y-%m-%d %H:%M"
def valid_time_range(start, end, tzname="UTC"):
tz = pytz.timezone(tzname or "UTC") # raises UnknownTimeZoneError early
s = datetime.datetime.strptime(start, TIME_FMT) if start else None
e = datetime.datetime.strptime(end, TIME_FMT) if end else None
if s and e and s > e:
raise ValueError("start must be <= end")
return True Type guard
import datetime, re
_TIME_RE = re.compile(r"^\d{4}-\d{2}-\d{2} \d{2}:\d{2}$")
def is_valid_range_str(value: str | None) -> bool:
return value is None or bool(_TIME_RE.match(value) and _parses(value))
def _parses(value):
try:
datetime.datetime.strptime(value, "%Y-%m-%d %H:%M")
return True
except ValueError:
return False Try / catch
try:
resp = client.get(f"/console/api/agent/{aid}/logs", params={"start": s, "end": e})
except HTTPError as err:
if err.response.status_code == 400:
raise ValueError(f"bad time range: {err.response.json().get('description')}") from err
raise Prevention
- Always URL-encode the space in `YYYY-MM-DD HH:MM`.
- Confirm the user's timezone is a valid IANA name before relying on it.
- Send start <= end and use the same format for both bounds.
When it happens
Trigger: An agent observability endpoint that calls `_parse_observability_time_range` receives a `start`/`end` query string that fails `parse_time_range` parsing: wrong format, unknown timezone on the account, or a start later than end.
Common situations: Client sends `?start=2024-13-01 10:00` (bad month), omits the time portion (`2024-01-01`), passes a swapped range, or the user's `account.timezone` is unset to an invalid tzdb name.
Related errors
AI-assisted analysis of langgenius/dify@ef8544b173 (2026-08-12).
Data as JSON: /api/errors/f2ef56beccd86a7c.
Report an issue: GitHub.