Moved from objectstack-ai/hotcrm#1879, where it was filed. It lands here: update_record is the platform's MCP tool surface, and hotcrm authors no part of it — the update_record hits in that repo are all the flow node type of the same name, and recordId appears there only in prose (.github/instructions/logic.md, CHANGELOG.md, docs/developers/code_examples.md), never as a schema. Routed by the repo:hotcrm seat (hotcrm#1353); ⛔ unassigned and unlabelled, for this repo's triage to grade.
Original reporter: @yinlianghui, from the steedos-labs/video-studio promo-film lane (#78), observed on a real Claude Code client against a real hotcrm service and re-checked from the byte stream rather than a text dump.
The observation
An update_record call written with id: instead of recordId: returns:
MCP error -32602: Input validation error: Invalid arguments for tool update_record:
Invalid input: expected string, received undefined at recordId
In the same recording, the only difference between the call that worked and the ones that failed is that parameter name:
✗ update_record(objectName:"crm_lead", id: "_IFp-Bf8yQcrfV8o", data:{"status":"qualified"}) → -32602
✓ update_record(objectName:"crm_lead", recordId:"_IFp-Bf8yQcrfV8o", data:{"status":"qualified"}) → normal response
Scale, counted on the byte stream after stripping ANSI
Three independent recordings — same instruction, same environment, same record:
| take |
update_record call sites |
sent id: |
sent recordId: |
Invalid arguments |
| v2 |
8 |
0 |
8 |
0 (clean) |
| v3 |
2 |
0 |
2 |
3 (see the second shape below) |
| v4 |
7 |
5 |
2 |
3 |
⇒ Non-deterministic. Same instruction, three different outcomes. ⛔ The report deliberately does not assert a specific input triggers it.
Why it is worth changing
- The error names
recordId as undefined while the caller sent id. So it does not say "you used the wrong name" — it says "you are missing a field you believe you already supplied", which invites the caller to retry the same shape. ⭐ That is the same failure class as hotcrm#1877 (now fixed): an error message that points at the field whose presence or absence the caller has already decided is correct, so an agent reads it as a repair instruction and loops.
id is the most natural guess for this parameter, and it is what most read/write paths use to mean a record's primary key.
Suggested, low-risk and non-blocking (the reporter's, and this seat is not ruling on it): accept id as an alias for recordId on update_record and its siblings (get_record / delete_record, if they name it the same way); or when validation fails with recordId missing and an unexpected id present, say so in the message.
⚠️ A second shape, recorded separately — ⛔ do not merge it with the above
In take v3 the failing calls had all three parameters undefined:
Invalid input: expected string, received undefined at objectName
Invalid input: expected string, received undefined at recordId
Invalid input: expected record, received undefined at data
⇒ that looks like the caller sending empty arguments, which is not the same thing as guessing a parameter name wrong. The report draws no conclusion on it and recommends no change; it is listed only because it came from the same batch and you may judge it same-origin.
Dedupe
Searched this repo before filing — 2 hits, both CLOSED, neither this: #16913 (query_records silently ignores unknown sort/filter keys) and #8266 (the stdio MCP record resource skipping the ADR-0049 exposure gate). ⚠️ Control: the query returned real MCP-tool cards, so the channel answers on this topic and the zero for the parameter-name issue is a reading rather than a dead search. The reporter had already searched hotcrm (zero, stated on the original card).
Not blocking anything
The reporter is consuming hotcrm read-only as a filming subject, made no changes, and is not claiming this. Their data layer wrote correctly every time — only the on-screen retries were affected. ⛔ No fix or timeline is requested.
Refs: objectstack-ai/hotcrm#1879 (origin, closed as moved) · objectstack-ai/hotcrm#1877 (the same error-message-induces-a-loop class, fixed) · steedos-labs/video-studio #78.
Moved from objectstack-ai/hotcrm#1879, where it was filed. It lands here:
update_recordis the platform's MCP tool surface, and hotcrm authors no part of it — theupdate_recordhits in that repo are all the flow node type of the same name, andrecordIdappears there only in prose (.github/instructions/logic.md,CHANGELOG.md,docs/developers/code_examples.md), never as a schema. Routed by therepo:hotcrmseat (hotcrm#1353); ⛔ unassigned and unlabelled, for this repo's triage to grade.Original reporter:
@yinlianghui, from thesteedos-labs/video-studiopromo-film lane (#78), observed on a real Claude Code client against a real hotcrm service and re-checked from the byte stream rather than a text dump.The observation
An
update_recordcall written withid:instead ofrecordId:returns:In the same recording, the only difference between the call that worked and the ones that failed is that parameter name:
Scale, counted on the byte stream after stripping ANSI
Three independent recordings — same instruction, same environment, same record:
update_recordcall sitesid:recordId:Invalid arguments⇒ Non-deterministic. Same instruction, three different outcomes. ⛔ The report deliberately does not assert a specific input triggers it.
Why it is worth changing
recordIdas undefined while the caller sentid. So it does not say "you used the wrong name" — it says "you are missing a field you believe you already supplied", which invites the caller to retry the same shape. ⭐ That is the same failure class as hotcrm#1877 (now fixed): an error message that points at the field whose presence or absence the caller has already decided is correct, so an agent reads it as a repair instruction and loops.idis the most natural guess for this parameter, and it is what most read/write paths use to mean a record's primary key.Suggested, low-risk and non-blocking (the reporter's, and this seat is not ruling on it): accept
idas an alias forrecordIdonupdate_recordand its siblings (get_record/delete_record, if they name it the same way); or when validation fails withrecordIdmissing and an unexpectedidpresent, say so in the message.In take v3 the failing calls had all three parameters undefined:
⇒ that looks like the caller sending empty arguments, which is not the same thing as guessing a parameter name wrong. The report draws no conclusion on it and recommends no change; it is listed only because it came from the same batch and you may judge it same-origin.
Dedupe
Searched this repo before filing — 2 hits, both CLOSED, neither this: #16913 (⚠️ Control: the query returned real MCP-tool cards, so the channel answers on this topic and the zero for the parameter-name issue is a reading rather than a dead search. The reporter had already searched hotcrm (zero, stated on the original card).
query_recordssilently ignores unknown sort/filter keys) and #8266 (the stdio MCP record resource skipping the ADR-0049 exposure gate).Not blocking anything
The reporter is consuming hotcrm read-only as a filming subject, made no changes, and is not claiming this. Their data layer wrote correctly every time — only the on-screen retries were affected. ⛔ No fix or timeline is requested.
Refs: objectstack-ai/hotcrm#1879 (origin, closed as moved) · objectstack-ai/hotcrm#1877 (the same error-message-induces-a-loop class, fixed) ·
steedos-labs/video-studio#78.