You have a comma instead of AND or OR in the 2 WHERE clauses.
Instead of (see comments -- <<<<<<<<<< ...
):-
SELECT *, (
SELECT SUM(records.amount) AS total_income FROM records
WHERE records.category = "income",
records.date BETWEEN DATE("now", "start of month") AND DATE("now", "start of month", "+1 month", "-1 day")
), (
SELECT SUM(records.amount) AS total_expense FROM records
WHERE records.category = "expense",
records.date BETWEEN DATE("now", "start of month") AND DATE("now", "start of month", "+1 month", "-1 day")
)
FROM accounts INNER JOIN records ON accounts.id = records.accountId;
Although not a syntax error, you probably want the AS clause outside of the subqueries
Try :-
SELECT *, (
SELECT SUM(records.amount) FROM records
WHERE records.category = "income" AND
records.date BETWEEN DATE("now", "start of month") AND DATE("now", "start of month", "+1 month", "-1 day")
) AS total_expense,
(
SELECT SUM(records.amount) FROM records
WHERE records.category = "expense" AND
records.date BETWEEN DATE("now", "start of month") AND DATE("now", "start of month", "+1 month", "-1 day")
) AS total_expense
FROM accounts INNER JOIN records ON accounts.id = records.accountId;
e.g.

- Note that each row will have the sum so it's not a running accumulation rather every result will have the same summed values.
Additional re comment :-
as you say I am getting "repeated rows" for every record associated
with an account and not an accumulation. I will pass this info to a
recyclerView Adapter so it would be a problem. Now I end the query
with FROM accounts and I get just one row per account with their
corresponding total.
I believe the following may be what you want or perhaps the basis of what you want:-
DROP TABLE IF EXISTS accounts;
DROP TABLE If EXISTS records;
CREATE TABLE IF NOT EXISTS records (amount INTEGER, category TEXT, date TEXT, accountId INTEGER);
CREATE TABLE IF NOT EXISTS accounts (id INTEGER PRIMARY KEY, accountname TEXT);
INSERT INTO accounts (accountname) VALUES('account1'),('account2');
INSERT INTO records (amount, category, date, accountId) VALUES
(300,'income','2018-12-31',1),
(25,'expense','2018-12-31',1),
(100,'income','2019-01-01',1),
(30,'expense','2019-01-01',1),
(40,'expense','2019-01-02',1),
(200,'income','2019,01-02',1),
(600,'income','2018-12-31',2),
(325,'expense','2018-12-31',2),
(700,'income','2019-01-01',2),
(330,'expense','2019-01-01',2),
(440,'expense','2019-01-02',2),
(5200,'income','2019,01-02',2)
;
SELECT *,
r.rowid AS ambiguos_recordsid,
date('now','start of month') AS startdate,
date('now','start of month', '+1 month', '-1 day') AS enddate,
r.date BETWEEN date('now','start of month') AND date('now','start of month', '+1 month', '-1 day') AS resultdate,
(
SELECT sum(amount)
FROM records
WHERE
records.rowid <= r.rowid AND category = 'income'
AND (date BETWEEN date('now','start of month') AND date('now','start of month', '+1 month', '-1 day'))
AND accountid = r.accountid
) AS rolling_income,
(
SELECT sum(amount)
FROM records
WHERE
records.rowid <= r.rowid AND category = 'expense'
AND (date BETWEEN date('now','start of month') AND date('now','start of month', '+1 month', '-1 day'))
AND accountid = r.accountid
) AS rolling_expense
FROM records AS r JOIN accounts on accountId = accounts.id
WHERE r.date BETWEEN date('now','start of month') AND date('now','start of month', '+1 month', '-1 day')
ORDER BY r.accountid, r.rowid
;
Using the above, the result is :-
