passbolt/passbolt_api · error · BadRequestException
The comment id is not valid.
Error message
The comment id is not valid.
What it means
CommentsUpdateController::update() validates the commentId route parameter as a UUID before doing anything else. If the id in the URL is not a valid UUID string it throws BadRequestException('The comment id is not valid.') producing a 400 response. This guards the service layer from receiving malformed identifiers.
Solutions
- Send a valid UUID comment id in the URL, obtained from the comment resource's own `id` field (e.g. from GET /comments/<resourceId>.json).
- Fix client code that interpolates the wrong id (parent resource id or numeric legacy id) into the comments endpoint.
- If migrating from a legacy integer-id integration, remap old ids to UUIDs before calling update.
Example fix
// before — wrong id used (parent resource id)
await api.put(`/comments/${resourceId}`, { content });
// after — use the comment's own UUID
const comment = comments.find(c => c.id === commentId);
if (!/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(comment.id)) throw new Error('bad comment id');
await api.put(`/comments/${comment.id}`, { content }); Defensive patterns
Strategy: validation
Validate before calling
// run before calling PUT /comments/<id>
const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
if (!UUID_RE.test(commentId)) throw new TypeError(`comment id must be a UUID, got: ${commentId}`); Type guard
const isCommentId = (v) => typeof v === 'string' && /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(v); Try / catch
try {
await api.put(`/comments/${commentId}`, { content });
} catch (e) {
if (e.response?.status === 400 && e.response?.data?.message === 'The comment id is not valid.') {
throw new Error('Check you are passing the comment UUID, not the parent resource id');
}
throw e;
} Prevention
- Take comment ids only from the comment resource's `id` field, never from parent resource responses.
- Add a UUID-format assertion at the API client boundary for all id path parameters.
- Use a typed id wrapper (CommentId) in client code to prevent mixing resource ids and comment ids.
- When porting from legacy integer-id integrations, remap ids before issuing updates.
When it happens
Trigger: PUT /comments/<commentId> where commentId is not a UUID v4 — e.g. a numeric database id, a slug, an empty string, a truncated or typosquatted UUID, or URL-encoded junk in the path segment.
Common situations: Client code building URLs from the wrong id field (resource id instead of comment id); older API integrations using integer ids from a pre-UUID schema; copied URL with missing or clipped id; manual curl testing with a made-up id.
Understand the failure class
Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.
Related errors
- Could not delete comment.
- Could not validate comment data.
- Invalid id
- Invalid model name
- Invalid query string. The contain parameter should be an…
AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17).
Data as JSON: /api/errors/4bdd6cbff719b802.
Report an issue: GitHub.
Appendix: source
Thrown at src/Controller/Comments/CommentsUpdateController.php:45
* @property \App\Model\Table\CommentsTable $Comments
*/
class CommentsUpdateController extends AppController
{
/**
* Update a comment.
*
* @param string $commentId The identifier of the comment to update
* @throws \Cake\Http\Exception\ForbiddenException
* @throws \Cake\Http\Exception\BadRequestException
* @throws \App\Error\Exception\ValidationException
* @return void
*/
public function update(string $commentId)
{
$this->assertJson();
if (!Validation::uuid($commentId)) {
throw new BadRequestException(__('The comment id is not valid.'));
}
$comment = (new CommentsUpdateService())->update(
$this->User->id(),
$commentId,
Hash::get($this->request->getData(), 'content')
);
$this->success(__('The comment was successfully updated.'), $comment);
}
}
View on GitHub (pinned to 31c1bbc10f)