fix: send board item labels as string, not array #42
No reviewers
Labels
No labels
domain:backend
domain:devops
domain:frontend
status:approved
status:in-progress
status:needs-fix
status:qa
type:bug
type:devops
type:feature
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
forgejo_admin/pal-e-mcp!42
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "41-fix-labels-array-to-string"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
The pal-e-docs API expects
labelsasstr | None(comma-separated string), butcreate_board_itemandupdate_board_itemwere splitting the input string into a Python list before sending it in the JSON body. This caused the API to receive a JSON array["type:bug", "scope:unplanned"]instead of the expected string"type:bug,scope:unplanned".Changes
src/pal_e_docs_mcp/tools/boards.py-- Changedcreate_board_itemandupdate_board_itemto rejoin labels into a comma-separated string after stripping whitespace, instead of sending a list. The whitespace normalization and trailing-comma handling are preserved.tests/test_param_alignment.py-- Updated existing assertions to expect strings instead of lists. Added new tests for whitespace stripping and trailing comma handling on bothcreate_board_itemandupdate_board_item.Test Plan
pytest tests/ -v)ruff formatandruff checkcleanReview Checklist
Related
add_board_itemmethod also typeslabelsaslist[str] | Nonewhich is inconsistent with the API schema -- that is a separate fix for pal-e-docs-sdk.Self-Review
Reviewed the diff. No issues found.
list->",".join(...)in bothcreate_board_itemandupdate_board_itemupdate_board_itemwithlabels=","would send""(empty string) rather than omitting the field. This matches pre-existing behavior forcreate_board_item(which also sends falsy values through). Not a regression and not in scope for this issue.add_board_itemalso typeslabelsaslist[str] | Noneinstead ofstr | None-- separate fix needed there.PR #42 Review
DOMAIN REVIEW
Tech stack: Python / MCP server wrapping pal-e-docs REST API via SDK HTTP helpers. Test framework: pytest with monkeypatched mock SDK.
Bug analysis: Verified the root cause. The pal-e-docs API defines
labelsasstr | Noneat every layer:labels: Mapped[str | None] = mapped_column(Text, nullable=True)(/home/ldraney/pal-e-docs/src/pal_e_docs/models.py:272)labels: str | None = None(/home/ldraney/pal-e-docs/src/pal_e_docs/schemas.py:252,288,296)The old code was calling
.split(",")to produce a Python list, then sending that list as JSON (an array). The fix correctly changes to.join()after stripping, preserving the whitespace normalization and trailing-comma handling while sending the API-expected string format.Code correctness:
create_board_item(line 186):labels_str = ",".join(lbl.strip() for lbl in labels.split(",") if lbl.strip()) if labels else None-- correct. Theif labelsguard handles bothNoneand""(empty string is falsy), producingNonewhich is then correctly excluded from the body by theif labels_str is not Nonecheck. This matches the existingtest_labels_empty_string_is_no_labelstest.update_board_item(line 242): Same pattern insideif labels is not None:guard -- correct. Theif lbl.strip()filter handles trailing commas.Both functions use the same normalization logic (DRY observation): The expression
",".join(lbl.strip() for lbl in labels.split(",") if lbl.strip())appears in bothcreate_board_itemandupdate_board_item. This is a minor duplication -- a small_normalize_labels(labels: str) -> strhelper would reduce it. However, this is a 1-liner repeated twice in the same file, and extracting it would be scope creep for a bugfix PR. Flagging as a nit only.Test coverage:
test_labels_csv_basicandtest_labels_csv_as_stringnow assert string output instead of list output.TestCreateBoardItem.test_labels_whitespace_stripped-- whitespace normalizationTestUpdateBoardItem.test_labels_whitespace_stripped-- whitespace normalizationTestUpdateBoardItem.test_labels_trailing_comma-- trailing comma handlingtest_labels_trailing_commaon create was already present and updated)None(via omission).PEP compliance: Type hints present. Docstrings present on tool functions. Generator expression in
.join()is idiomatic Python. Variable renamed fromlabels_listtolabels_strto accurately reflect the type -- good.SDK inconsistency noted: The PR body correctly identifies that
pal-e-docs-sdktypeslabelsaslist[str] | Noneinadd_board_item(/home/ldraney/pal-e-docs-sdk/src/pal_e_docs_sdk/boards.py:105), which is inconsistent with the API schema. This is correctly scoped out as a separate fix. The MCP tools bypass the SDK board methods (using raw.post()/.patch()), so this SDK inconsistency does not affect this PR.BLOCKERS
None.
NITS
",".join(lbl.strip() for lbl in labels.split(",") if lbl.strip())is duplicated acrosscreate_board_item(line 186) andupdate_board_item(line 242). A small_normalize_labels(labels: str) -> strhelper would reduce this to a single definition. Non-blocking -- the duplication is in a data formatting path, not an auth/security path.SOP COMPLIANCE
41-fix-labels-array-to-stringreferences #41)Closes #41fix: send board item labels as string, not array)plan-pal-e-docsper SOP)PROCESS OBSERVATIONS
pal-e-docs-sdk) has the same type mismatch (list[str] | Nonevs API'sstr | None). The PR correctly scopes this out but it should be tracked as a follow-up issue onpal-e-docs-sdk.VERDICT: APPROVED