louislam/uptime-kuma · info · Error

Invalid db-config.json, it must be an object

Error message

Invalid db-config.json, it must be an object

What it means

Thrown locally by autoGetTelegramChatID (Telegram.vue:198) when the Telegram bot getUpdates call returns successfully but res.data.result is empty (length < 1). With no update entries there is nothing to derive a chat ID from, so the code throws to tell the user the bot has not yet received any interaction. It is caught and shown as a toast, signalling a setup step is still missing.

Source

Thrown at server/database.js:212

        } catch (e) {
            return "";
        }
    }

    /**
     * Read the database config
     * @throws {Error} If the config is invalid
     * @typedef {string|undefined} envString
     * @returns {{type: "sqlite"} | {type:envString, hostname:envString, port:envString, database:envString, username:envString, password:envString, socketPath:envString}} Database config
     */
    static readDBConfig() {
        let dbConfig;

        let dbConfigString = fs.readFileSync(path.join(Database.dataDir, "db-config.json")).toString("utf-8");
        dbConfig = JSON.parse(dbConfigString);

        if (typeof dbConfig !== "object") {
            throw new Error("Invalid db-config.json, it must be an object");
        }

        if (typeof dbConfig.type !== "string") {
            throw new Error("Invalid db-config.json, type must be a string");
        }
        return dbConfig;
    }

    /**
     * @typedef {string|undefined} envString
     * @param {{type: "sqlite"} | {type:envString, hostname:envString, port:envString, database:envString, username:envString, password:envString, socketPath:envString}} dbConfig the database configuration that should be written
     * @returns {void}
     */
    static writeDBConfig(dbConfig) {
        fs.writeFileSync(path.join(Database.dataDir, "db-config.json"), JSON.stringify(dbConfig, null, 4));
    }

    /**

View on GitHub (pinned to 6b5ea01557)

Solutions

  1. In Telegram, open a chat with the bot and send /start (or post once to the target channel with the bot added), then click 'Auto Get' again.
  2. Open the telegramGetUpdatesURL link shown in the form in a browser and confirm the JSON has ok:true with a populated result array.
  3. If a webhook is set elsewhere, remove it via the Telegram deleteWebhook endpoint, then retry getUpdates.
  4. Leave telegramServerUrl at its default https://api.telegram.org unless you genuinely run a local Bot API server, and trim whitespace from the token.

Example fix

// before
if (res.data.result.length >= 1) {
    // ...extract chat id...
} else {
    throw new Error(this.$t("chatIDNotFound"));
}

// after: validate response shape first, separate the two failure modes
if (!res.data || res.data.ok !== true || !Array.isArray(res.data.result)) {
    throw new Error(this.$t("chatIDNotFound"));
}
if (res.data.result.length === 0) {
    throw new Error(this.$t("telegramNoUpdatesYet"));
}
Defensive patterns

Strategy: validation

Validate before calling

// Validate the response envelope before checking length
const res = await axios.get(this.telegramGetUpdatesURL("withToken"));
if (!res.data || res.data.ok !== true) {
    this.$root.toastError(this.$t("telegramTokenInvalid"));
    return;
}
if (!Array.isArray(res.data.result) || res.data.result.length === 0) {
    this.$root.toastError(this.$t("telegramNoUpdatesYet"));
    return;
}
// safe to inspect updates here

Type guard

// Confirm the Telegram getUpdates payload shape
function isTelegramUpdatesEnvelope(payload) {
    return payload != null
        && payload.ok === true
        && Array.isArray(payload.result);
}

if (!isTelegramUpdatesEnvelope(res.data)) {
    this.$root.toastError(this.$t("chatIDNotFound"));
    return;
}

Try / catch

try {
    const res = await axios.get(this.telegramGetUpdatesURL("withToken"));
    if (!isTelegramUpdatesEnvelope(res.data) || res.data.result.length === 0) {
        throw new Error(this.$t("telegramNoUpdatesYet"));
    }
    // ...extract chat id...
} catch (error) {
    const msg = error.response
        ? `${error.message} (HTTP ${error.response.status})`
        : error.message;
    this.$root.toastError(msg);
}

Prevention

When it happens

Trigger: Clicking 'Auto Get' when res.data.result is an empty array. This occurs when the bot has never been messaged, when updates were already acknowledged by a prior getUpdates call carrying an offset, or when a webhook is currently registered for the bot (the Telegram Bot API returns 409 Conflict / no usable getUpdates payload while a webhook is active). Also possible if telegramServerUrl points at a local Bot API server that returns a different shape.

Common situations: User pasted a freshly created bot token but never pressed /start in Telegram. A webhook was set by another integration so polling yields nothing. A custom telegramServerUrl was configured (Telegram.vue:60) that is unreachable or returns an unexpected body. A token with stray whitespace produces an ok:false response, leaving result absent or empty.

Related errors


AI-assisted analysis of louislam/uptime-kuma@6b5ea01557 (2026-08-12). Data as JSON: /api/errors/973fd90a785a27f0. Report an issue: GitHub.