{"record":{"id":"1ad7ef1e0276c01c","repo":"apache/cassandra","slug":"got-null-for-insert-json-values-1ad7ef","errorCode":null,"errorMessage":"Got null for INSERT JSON values","messagePattern":"Got null for INSERT JSON values","errorType":"validation","errorClass":"InvalidRequestException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/cql3/QueryOptions.java","lineNumber":201,"sourceCode":"     * @param columnName the name of the column we want the value of.\n     * @param expectedReceivers the columns expected in the JSON value at index {@code bindIndex}. This is only used when parsing the\n     * json initially and no check is done afterwards. So in practice, any call of this method on the same QueryOptions object and with the same\n     * {@code bindIndx} values should use the same value for this parameter, but this isn't validated in any way.\n     *\n     * @return the value correspong to column {@code columnName} in the (JSON) bind value at index {@code bindIndex}. This may return null if the\n     * JSON value has no value for this column.\n     */\n    public Term getJsonColumnValue(int bindIndex, ColumnIdentifier columnName, Collection<ColumnMetadata> expectedReceivers) throws InvalidRequestException\n    {\n        if (jsonValuesCache == null)\n            jsonValuesCache = new ArrayList<>(Collections.<Map<ColumnIdentifier, Term>>nCopies(getValues().size(), null));\n\n        Map<ColumnIdentifier, Term> jsonValue = jsonValuesCache.get(bindIndex);\n        if (jsonValue == null)\n        {\n            ByteBuffer value = getValues().get(bindIndex);\n            if (value == null)\n                throw new InvalidRequestException(\"Got null for INSERT JSON values\");\n\n            jsonValue = Json.parseJson(UTF8Type.instance.getSerializer().deserialize(value), expectedReceivers);\n            jsonValuesCache.set(bindIndex, jsonValue);\n        }\n\n        return jsonValue.get(columnName);\n    }\n\n    /**\n     * Tells whether or not this <code>QueryOptions</code> contains the column specifications for the bound variables.\n     * <p>The column specifications will be present only for prepared statements.</p>\n     * @return <code>true</code> this <code>QueryOptions</code> contains the column specifications for the bound\n     * variables, <code>false</code> otherwise.\n     */\n    public boolean hasColumnSpecifications()\n    {\n        return false;\n    }","sourceCodeStart":183,"sourceCodeEnd":219,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/cql3/QueryOptions.java#L183-L219","documentation":"QueryOptions.getJsonColumnValue() reads the bound value for an INSERT JSON statement. A null ByteBuffer at the bind index means no value was supplied for the JSON payload, so Json.parseJson would have nothing to parse; the driver/client sent an unset or null bind marker for the JSON value.","triggerScenarios":"INSERT INTO ... JSON ? with the JSON string bind parameter bound to null or left unset (UNSET_BYTE_BUFFER pathway), or a driver sending an insufficient number of values so getValues().get(bindIndex) is null.","commonSituations":"Driver bug or misuse of the raw protocol binding fewer values than markers; application code passing a null JSON string; serializing batch statements where one JSON insert lacks its bound value.","solutions":["Bind a valid JSON string (non-null) to the INSERT JSON parameter before executing.","Verify the number of positional values matches the number of bind markers in the statement.","Check the driver version for known bugs around JSON bind values and unset values."],"exampleFix":"// before\nsession.execute(stmt.bind(null));\n// after\nString json = \"{\\\"id\\\":1,\\\"name\\\":\\\"a\\\"}\";\nsession.execute(stmt.bind(json));","handlingStrategy":"type-guard","validationCode":"if (jsonString == null || jsonString.isEmpty()) throw new IllegalArgumentException(\"INSERT JSON requires a non-null JSON string\");","typeGuard":"if (!(json instanceof String) || ((String) json).isEmpty()) throw new IllegalArgumentException(\"JSON payload must be a non-empty string\");","tryCatchPattern":"try { session.execute(jsonInsert.bind(json)); } catch (InvalidRequestException e) { if (e.getMessage().contains(\"Got null for INSERT JSON values\")) { /* fix binding */ } }","preventionTips":["Always bind a real value to JSON insert markers","Assert value count equals marker count before execute","Avoid null JSON strings in data pipelines"],"tags":["cql","json","bind-parameters","null-value"],"backgroundTag":"null-argument","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}