{"record":{"id":"f89f84ac0548d1af","repo":"paperclipai/paperclip","slug":"rememberaction-must-be-a-boolean","errorCode":null,"errorMessage":"rememberAction must be a boolean","messagePattern":"rememberAction must be a boolean","errorType":"validation","errorClass":null,"httpStatus":400,"severity":"warning","filePath":"server/src/routes/tool-gateway.ts","lineNumber":589,"sourceCode":"        tool: body.tool,\n        parameters: body.parameters ?? {},\n        timeoutMs: body.timeoutMs,\n        approvedActionRequestId:\n          typeof body.approvedActionRequestId === \"string\" ? body.approvedActionRequestId : null,\n        idempotencyKey: typeof body.idempotencyKey === \"string\" ? body.idempotencyKey : null,\n        callerHeaders: callerHeaders(req),\n      });\n      res.json(result);\n    } catch (err) {\n      sendGatewayError(res, err);\n    }\n  });\n\n  router.post(\"/tool-gateway/action-requests/:id/approve\", async (req, res) => {\n    try {\n      assertBoard(req);\n      const body = (req.body ?? {}) as { companyId?: string; rememberAction?: boolean };\n      if (body.rememberAction !== undefined && typeof body.rememberAction !== \"boolean\") { res.status(400).json({ error: \"rememberAction must be a boolean\" }); return; }\n      const companyId = body.companyId ?? (typeof req.query.companyId === \"string\" ? req.query.companyId : null);\n      if (!companyId) {\n        res.status(400).json({ error: \"companyId is required\" });\n        return;\n      }\n      assertBoardMutationAccess(req, companyId);\n      const actor = getActorInfo(req);\n      const actionRequest = await toolGateway.approveActionRequest({\n        companyId,\n        actionRequestId: req.params.id,\n        rememberAction: body.rememberAction,\n        actor: {\n          agentId: actor.agentId,\n          userId: req.actor.type === \"board\" ? req.actor.userId : null,\n        },\n      });\n      res.json(actionRequest);\n    } catch (err) {","sourceCodeStart":571,"sourceCodeEnd":607,"githubUrl":"https://github.com/paperclipai/paperclip/blob/01ad8584922b5d85292b1723cae71fa0d9b07a19/server/src/routes/tool-gateway.ts#L571-L607","documentation":"HTTP 400 validation on the tool-gateway approve endpoint: the request body includes rememberAction but it is not a boolean. The handler explicitly allows it to be omitted (undefined) but rejects any other type.","triggerScenarios":"POST /api/tool-gateway/action-requests/:id/approve with body { rememberAction: \"true\" } (string), { rememberAction: 1 }, or { rememberAction: null } — typeof body.rememberAction !== 'boolean' while the key is present.","commonSituations":"Client sends JSON booleans as strings; form-encoded clients stringify true; SDK serializes a nullable boolean as null; copy-pasted curl with quoted 'true'.","solutions":["Send rememberAction as a real JSON boolean: {\"rememberAction\": true}.","Omit the key entirely if you don't want the decision remembered.","Fix the client serializer to map boolean flags to JSON booleans, not strings.","If using a form/query builder, coerce with rememberAction === 'true' on the client before sending."],"exampleFix":"// before\nfetch(url, { method: 'POST', body: JSON.stringify({ companyId, rememberAction: 'true' }) })\n// 400 rememberAction must be a boolean\n// after\nfetch(url, { method: 'POST', body: JSON.stringify({ companyId, rememberAction: true }) })","handlingStrategy":"validation","validationCode":"if (rememberAction !== undefined && typeof rememberAction !== 'boolean') throw new TypeError('rememberAction must be a boolean or omitted');","typeGuard":"const isBoolOrUndefined = (v) => typeof v === 'boolean' || v === undefined;","tryCatchPattern":"try {\n  const res = await approveActionRequest({ id, companyId, rememberAction });\n} catch (e) {\n  if (e.status === 400 && /rememberAction/.test(e.body?.error ?? '')) {\n    return approveActionRequest({ id, companyId }); // retry without the flag\n  }\n  throw e;\n}","preventionTips":["Never stringify booleans in JSON request bodies.","Use a typed client so rememberAction is boolean at compile time.","Omit optional flags rather than sending null.","Add client-side schema validation (e.g. Zod) before POSTing."],"tags":["validation","http-400","request-body","boolean"],"backgroundTag":"invalid-argument-value","analyzedSha":"01ad8584922b5d85292b1723cae71fa0d9b07a19","analyzedAt":"2026-09-10T03:14:50.855Z","contentChangedAt":"2026-09-10T03:14:50.855Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}