diff --git a/io/dap_context.c b/io/dap_context.c
index 0334ccba30c4ea22bbe87d72815d7493bb071b6f..5a2b8d0b6a83b695e1ba2363ff7b02e8210da197 100644
--- a/io/dap_context.c
+++ b/io/dap_context.c
@@ -552,7 +552,7 @@ int dap_worker_thread_loop(dap_context_t * a_context)
                     if (l_cur->callbacks.read_callback) {
                         l_cur->last_time_active = time(NULL);
                         debug_if(g_debug_reactor, L_DEBUG, "Received %lu bytes from socket %zu", l_bytes, l_cur->socket);
-                        l_cur->callbacks.read_callback(l_cur, NULL);
+                        l_cur->callbacks.read_callback(l_cur, l_cur->callbacks.arg);
                         if (!l_cur->context) {
                             debug_if(g_debug_reactor, L_DEBUG, "Es %p : %zu unattached from context %u", l_cur, l_cur->socket, a_context->id);
                             continue;
diff --git a/io/dap_events_socket.c b/io/dap_events_socket.c
index 979519dc4520fe0cd56161fed84b3214d867076e..2d13cc923e687570892a5b4d6c5c4ea36a6b1708 100644
--- a/io/dap_events_socket.c
+++ b/io/dap_events_socket.c
@@ -1325,8 +1325,8 @@ void dap_events_socket_set_readable_unsafe_ex(dap_events_socket_t *a_es, bool a_
         return;
     default:
         a_es->pending_read = 0;
-        log_it(L_ERROR, "Operation \"%s\" on [%s] "DAP_FORMAT_ESOCKET_UUID" failed with error %lu",
-                        func, dap_events_socket_get_type_str(a_es), a_es->uuid, l_err);
+        log_it(L_ERROR, "Operation \"%s\" on [%s] "DAP_FORMAT_ESOCKET_UUID" failed with error %ld: \"%s\"",
+                        func, dap_events_socket_get_type_str(a_es), a_es->uuid, l_err, dap_strerror(l_err));
         if ( a_es->callbacks.error_callback )
             a_es->callbacks.error_callback(a_es, l_err);
         if ( !a_es->no_close )
@@ -1428,8 +1428,8 @@ void dap_events_socket_set_writable_unsafe_ex( dap_events_socket_t *a_es, bool a
         return;
     default:
         --a_es->pending_write;
-        log_it(L_ERROR, "Operation \"%s\" on [%s] "DAP_FORMAT_ESOCKET_UUID" failed with error %lu",
-                        func, dap_events_socket_get_type_str(a_es), a_es->uuid, l_err);
+        log_it(L_ERROR, "Operation \"%s\" on [%s] "DAP_FORMAT_ESOCKET_UUID" failed with error %ld: \"%s\"",
+                        func, dap_events_socket_get_type_str(a_es), a_es->uuid, l_err, dap_strerror(l_err));
         if ( a_es->callbacks.error_callback )
             a_es->callbacks.error_callback(a_es, l_err);
         if ( !a_es->no_close )
diff --git a/net/server/cli_server/dap_cli_server.c b/net/server/cli_server/dap_cli_server.c
index 4b11c72971743c7ea51be9b4014ca1cc8b4c7512..172fb23b14726cdc40b5d0cd9c51663a7c7da8d0 100644
--- a/net/server/cli_server/dap_cli_server.c
+++ b/net/server/cli_server/dap_cli_server.c
@@ -64,43 +64,60 @@ typedef struct cli_cmd_arg {
     dap_worker_t *worker;
     dap_events_socket_uuid_t es_uid;
     size_t buf_size;
-    char buf[];
+    char *buf, status;
 } cli_cmd_arg_t;
 
 static bool s_cli_cmd_exec(void *a_arg);
 
-DAP_STATIC_INLINE void s_cli_cmd_schedule(dap_events_socket_t *a_es, UNUSED_ARG void *a_arg) {
-    static const char l_content_len_str[] = "Content-Length: ";
-    char *l_len_token = strstr((char*)a_es->buf_in, l_content_len_str);
-#define m_dump_error_and_ret ({ \
-    const char l_error_str[] = "{ \"type\": 0, \"result\":\" Invalid request\", \"errors\": null, \"id\": 1 }", \
-        l_err_format_str[] = "HTTP/1.1 400 Bad Request\r\nContent-Length: %zu\r\n\r\n%s"; \
-    dap_events_socket_write_f_unsafe(a_es, l_err_format_str, sizeof(l_error_str) - 1, l_error_str); \
-    char *buf_dump = dap_dump_hex(a_es->buf_in, dap_max(a_es->buf_in_size, (size_t)65536)); \
-    log_it(L_DEBUG, "Incomplete cmd request: %s", buf_dump); \
-    DAP_DELETE(buf_dump); \
-})
-    if (!l_len_token || !strpbrk(l_len_token, "\r\n"))
-        return m_dump_error_and_ret;
-    long l_cmd_len = strtol(l_len_token + sizeof(l_content_len_str) - 1, NULL, 10);
-    
-    if (!l_cmd_len || l_cmd_len > 65536)
-        return m_dump_error_and_ret;
-
-    static const char l_head_end_str[] = "\r\n\r\n";
-    char *l_hdr_end_token = strstr(l_len_token, l_head_end_str);
-    if (!l_hdr_end_token)
-        return m_dump_error_and_ret;
-    else
-        l_hdr_end_token += ( sizeof(l_head_end_str) - 1 );
-    if (a_es->buf_in_size > l_cmd_len + (size_t)(l_hdr_end_token - (char*)a_es->buf_in))
-        return m_dump_error_and_ret;
-    cli_cmd_arg_t *l_arg = DAP_NEW_Z_SIZE(cli_cmd_arg_t, sizeof(cli_cmd_arg_t) + l_cmd_len + 1);
-    *l_arg = (cli_cmd_arg_t){ .worker = a_es->worker, .es_uid = a_es->uuid, .buf_size = l_cmd_len };
-    memcpy(l_arg->buf, l_hdr_end_token, l_cmd_len);
-    dap_proc_thread_callback_add_pri(NULL, s_cli_cmd_exec, l_arg, DAP_QUEUE_MSG_PRIORITY_HIGH);
-    a_es->buf_in_size = 0;
-#undef m_dump_error_and_ret
+DAP_STATIC_INLINE void s_cli_cmd_schedule(dap_events_socket_t *a_es, void *a_arg) {
+    cli_cmd_arg_t *l_arg = a_arg ? (cli_cmd_arg_t*)a_arg : DAP_NEW_Z(cli_cmd_arg_t);
+    switch (l_arg->status) {
+    case 0: {
+        a_es->callbacks.arg = l_arg;
+        ++l_arg->status;
+    }
+    case 1: {
+        static const char l_content_len_str[] = "Content-Length: ";
+        l_arg->buf = strstr((char*)a_es->buf_in, l_content_len_str);
+        if ( !l_arg->buf || !strpbrk(l_arg->buf, "\r\n") )
+            return;
+        if (( l_arg->buf_size = (size_t)strtol(l_arg->buf + sizeof(l_content_len_str) - 1, NULL, 10) ))
+            ++l_arg->status;
+        else
+            break;
+    }
+    case 2: { // Find header end and throw out header
+        static const char l_head_end_str[] = "\r\n\r\n";
+        char *l_hdr_end_token = strstr(l_arg->buf, l_head_end_str);
+        if (!l_hdr_end_token)
+            return;
+        l_arg->buf = l_hdr_end_token + sizeof(l_head_end_str) - 1;
+        ++l_arg->status;
+    }
+    case 3:
+    default: {
+        size_t l_hdr_len = (size_t)(l_arg->buf - (char*)a_es->buf_in);
+        if ( a_es->buf_in_size < l_arg->buf_size + l_hdr_len )
+            return;
+        l_arg->buf = DAP_DUP_SIZE(l_arg->buf, l_arg->buf_size);
+        l_arg->worker = a_es->worker;
+        l_arg->es_uid = a_es->uuid;
+        dap_proc_thread_callback_add_pri(NULL, s_cli_cmd_exec, l_arg, DAP_QUEUE_MSG_PRIORITY_HIGH);
+        a_es->buf_in_size = 0;
+        a_es->callbacks.arg = NULL;
+        return;
+    }
+    }
+
+    dap_events_socket_write_f_unsafe(a_es, "HTTP/1.1 500 Internal Server Error\r\n");
+    char *buf_dump = dap_dump_hex(a_es->buf_in, dap_min(a_es->buf_in_size, (size_t)65536));
+    log_it(L_DEBUG, "Incomplete cmd request:\r\n%s", buf_dump);
+    DAP_DELETE(buf_dump);
+    a_es->flags |= DAP_SOCK_SIGNAL_CLOSE;
+}
+
+DAP_STATIC_INLINE void s_cli_cmd_delete(dap_events_socket_t *a_es, void UNUSED_ARG *a_arg) {
+    DAP_DELETE(a_es->callbacks.arg);
 }
 
 /**
@@ -114,7 +131,7 @@ DAP_STATIC_INLINE void s_cli_cmd_schedule(dap_events_socket_t *a_es, UNUSED_ARG
 int dap_cli_server_init(bool a_debug_more, const char *a_cfg_section)
 {
     s_debug_cli = a_debug_more;
-    dap_events_socket_callbacks_t l_callbacks = { .read_callback = s_cli_cmd_schedule };
+    dap_events_socket_callbacks_t l_callbacks = { .read_callback = s_cli_cmd_schedule, .delete_callback = s_cli_cmd_delete };
     if (!( s_cli_server = dap_server_new(a_cfg_section, NULL, &l_callbacks) )) {
         log_it(L_ERROR, "CLI server not initialized");
         return -2;
@@ -363,8 +380,7 @@ static bool s_cli_cmd_exec(void *a_arg) {
                                             "%s", dap_strlen(l_ret), l_ret);
     dap_events_socket_write_mt(l_arg->worker, l_arg->es_uid, l_full_ret, dap_strlen(l_full_ret));
     // TODO: pagination
-    //dap_events_socket_remove_and_delete_mt(l_arg->worker, l_arg->es_uid); // No need...
-    DAP_DEL_MULTY(l_ret, /*l_full_ret,*/ a_arg);
+    DAP_DEL_MULTY(l_ret, l_arg->buf, /* l_full_ret, */ l_arg);
     return false;
 }
 
diff --git a/net/server/json_rpc/rpc_core/src/dap_json_rpc_params.c b/net/server/json_rpc/rpc_core/src/dap_json_rpc_params.c
index 09059eb900edee63eae90218c64f66ea3f284afb..901a5b09625d9eccec18525df13ecd2de0faba51 100644
--- a/net/server/json_rpc/rpc_core/src/dap_json_rpc_params.c
+++ b/net/server/json_rpc/rpc_core/src/dap_json_rpc_params.c
@@ -4,22 +4,13 @@
 
 dap_json_rpc_param_t* dap_json_rpc_create_param(void * data, dap_json_rpc_type_param_t type)
 {
-    dap_json_rpc_param_t *param = DAP_NEW(dap_json_rpc_param_t);
-    if (!param) {
-        log_it(L_CRITICAL, "%s", c_error_memory_alloc);
-        return NULL;
-    }
-
-    param->value_param = data;
-    param->type = type;
-
-    return param;
+    dap_json_rpc_param_t param = { .type = type, .value_param = data };
+    return DAP_DUP(&param);
 }
 
 dap_json_rpc_params_t* dap_json_rpc_params_create(void)
 {
-    dap_json_rpc_params_t *params = DAP_NEW_Z_RET_VAL_IF_FAIL(dap_json_rpc_params_t, NULL);
-    return params;
+    return DAP_NEW_Z(dap_json_rpc_params_t);
 }
 
 void dap_json_rpc_params_add_data(dap_json_rpc_params_t *a_params, const void *a_value,
@@ -59,11 +50,13 @@ void dap_json_rpc_params_add_param(dap_json_rpc_params_t *a_params, dap_json_rpc
 
 void dap_json_rpc_param_remove(dap_json_rpc_param_t *param)
 {
+    dap_return_if_fail(param);
     DAP_DEL_MULTY(param->value_param, param);
 }
 
 void dap_json_rpc_params_remove_all(dap_json_rpc_params_t *a_params)
 {
+    dap_return_if_fail(a_params);
     for (uint32_t i=0x0 ; i < dap_json_rpc_params_length(a_params); i++){
         dap_json_rpc_param_remove(a_params->params[i]);
     }
@@ -72,17 +65,17 @@ void dap_json_rpc_params_remove_all(dap_json_rpc_params_t *a_params)
 
 uint32_t dap_json_rpc_params_length(dap_json_rpc_params_t *a_params)
 {
-    return a_params->length;
+    return a_params ? a_params->length : 0;
 }
 
 void *dap_json_rpc_params_get(dap_json_rpc_params_t *a_params, uint32_t index)
 {
-    return a_params->length > index ? a_params->params[index]->value_param : NULL;
+    return a_params && a_params->length > index ? a_params->params[index]->value_param : NULL;
 }
 
 dap_json_rpc_type_param_t dap_json_rpc_params_get_type_param(dap_json_rpc_params_t *a_params, uint32_t index)
 {
-    return a_params->length > index ? a_params->params[index]->type : TYPE_PARAM_NULL;
+    return a_params && a_params->length > index ? a_params->params[index]->type : TYPE_PARAM_NULL;
 }
 
 dap_json_rpc_params_t * dap_json_rpc_params_create_from_array_list(json_object *a_array_list)
diff --git a/net/server/json_rpc/rpc_core/src/dap_json_rpc_response.c b/net/server/json_rpc/rpc_core/src/dap_json_rpc_response.c
index 78e9187946bc4b417be69f996dfe074428249258..d5769c9f386478a3d05b1145ec70ab75a40548c0 100644
--- a/net/server/json_rpc/rpc_core/src/dap_json_rpc_response.c
+++ b/net/server/json_rpc/rpc_core/src/dap_json_rpc_response.c
@@ -18,11 +18,7 @@ dap_json_rpc_response_t* dap_json_rpc_response_create(void * result, dap_json_rp
         return NULL;
     }
 
-    dap_json_rpc_response_t *response = DAP_NEW(dap_json_rpc_response_t);
-    if (!response) {
-        log_it(L_CRITICAL, "%s", c_error_memory_alloc);
-        return NULL;
-    }
+    dap_json_rpc_response_t *response = DAP_NEW_Z_RET_VAL_IF_FAIL(dap_json_rpc_response_t, NULL);
     
     response->id = id;
     response->type = type;