Problem / motivation
list_time_entries cannot read back time entries. Two independent bugs, both
surfaced while verifying a real entry against a live OpenProject instance:
Bug A — work-package filter rejected.
list_time_entries(work_package_id=…) builds
filters=[{"work_package": {"operator": "=", "values": [id]}}].
OpenProject's /time_entries endpoint rejects this:
API Error 400: {"_type":"Error",
"errorIdentifier":"urn:openproject-org:api:v3:errors:InvalidQuery",
"message":"Filters Work package filter does not exist."}
The filter identifier is wrong for the time-entries query (its filter set differs
from the work-packages query). The correct identifier must be verified against the
instance's time-entries query schema.
Bug B — hours sum crashes.
The tool does total_hours = 0 then total_hours += entry.get('hours', 0), but the
API returns hours as an ISO-8601 duration string (e.g. "PT4H"). So as soon as
any entry is present:
TypeError: unsupported operand type(s) for +=: 'int' and 'str'
The per-entry line also prints the raw PT4H instead of a number.
Net effect: list_time_entries is unusable whenever entries exist — it either 400s
(work-package filter) or raises TypeError (hours sum).
Scope / proposed approach
- Bug A: replace the
work_package filter identifier with the correct
time-entries filter name, verified against the instance's query schema. Audit the
user filter name in the same tool while at it (same filter set).
- Bug B: parse the ISO-8601 duration to float hours for both the per-entry
display and the running total; guard None/non-numeric so a malformed value can't
crash the whole listing.
- Keep the diff single-purpose — no unrelated reformatting.
Files: src/tools/time_entries.py (list_time_entries); possibly src/client.py
(get_time_entries).
Acceptance criteria
list_time_entries(work_package_id=X) and list_time_entries(user_id=Y) both
return entries with a correct numeric total — no InvalidQuery, no TypeError.
- Per-entry hours render as a number (e.g.
4.0), not PT4H.
- Network-free unit test in the existing style: a mocked entry with
hours="PT4H"
→ total 4.0, no crash; and the built filter uses the corrected identifier.
- Filter-name change verified against a running instance (gated live test /
ephemeral Docker).
Out of scope
- No unrelated reformatting or refactoring.
- No new filters/features beyond fixing the two bugs.
Notes
Independent of the input-serialization work (PR AndyEverything#22) — a pre-existing bug on main,
so it branches off main as a clean standalone fix.
Problem / motivation
list_time_entriescannot read back time entries. Two independent bugs, bothsurfaced while verifying a real entry against a live OpenProject instance:
Bug A — work-package filter rejected.
list_time_entries(work_package_id=…)buildsfilters=[{"work_package": {"operator": "=", "values": [id]}}].OpenProject's
/time_entriesendpoint rejects this:The filter identifier is wrong for the time-entries query (its filter set differs
from the work-packages query). The correct identifier must be verified against the
instance's time-entries query schema.
Bug B — hours sum crashes.
The tool does
total_hours = 0thentotal_hours += entry.get('hours', 0), but theAPI returns
hoursas an ISO-8601 duration string (e.g."PT4H"). So as soon asany entry is present:
The per-entry line also prints the raw
PT4Hinstead of a number.Net effect:
list_time_entriesis unusable whenever entries exist — it either 400s(work-package filter) or raises
TypeError(hours sum).Scope / proposed approach
work_packagefilter identifier with the correcttime-entries filter name, verified against the instance's query schema. Audit the
userfilter name in the same tool while at it (same filter set).display and the running total; guard
None/non-numeric so a malformed value can'tcrash the whole listing.
Files:
src/tools/time_entries.py(list_time_entries); possiblysrc/client.py(
get_time_entries).Acceptance criteria
list_time_entries(work_package_id=X)andlist_time_entries(user_id=Y)bothreturn entries with a correct numeric total — no
InvalidQuery, noTypeError.4.0), notPT4H.hours="PT4H"→ total
4.0, no crash; and the built filter uses the corrected identifier.ephemeral Docker).
Out of scope
Notes
Independent of the input-serialization work (PR AndyEverything#22) — a pre-existing bug on
main,so it branches off
mainas a clean standalone fix.